1
1
import { confirm } from '@inquirer/prompts' ;
2
2
import chalk from 'chalk' ;
3
- import { formatUnits } from 'ethers/lib/utils.js' ;
4
3
import yargs from 'yargs' ;
5
4
6
- import { MultiProvider } from '@hyperlane-xyz/sdk' ;
7
- import { LogFormat , LogLevel , configureRootLogger } from '@hyperlane-xyz/utils' ;
5
+ import {
6
+ LogFormat ,
7
+ LogLevel ,
8
+ configureRootLogger ,
9
+ rootLogger ,
10
+ } from '@hyperlane-xyz/utils' ;
8
11
9
12
import { Contexts } from '../../config/contexts.js' ;
10
13
import { safes } from '../../config/environments/mainnet3/owners.js' ;
11
14
import { Role } from '../../src/roles.js' ;
12
- import { executeTx , getSafeAndService } from '../../src/utils/safe.js' ;
15
+ import {
16
+ SafeTxStatus ,
17
+ executeTx ,
18
+ getPendingTxsForChains ,
19
+ } from '../../src/utils/safe.js' ;
13
20
import { withChains } from '../agent-utils.js' ;
14
21
import { getEnvironmentConfig } from '../core-utils.js' ;
15
22
16
- export enum SafeTxStatus {
17
- NO_CONFIRMATIONS = '🔴' ,
18
- PENDING = '🟡' ,
19
- ONE_AWAY = '🔵' ,
20
- READY_TO_EXECUTE = '🟢' ,
21
- }
22
-
23
- type SafeStatus = {
24
- chain : string ;
25
- nonce : number ;
26
- submissionDate : string ;
27
- shortTxHash : string ;
28
- fullTxHash : string ;
29
- confs : number ;
30
- threshold : number ;
31
- status : string ;
32
- balance : string ;
33
- } ;
34
-
35
- export async function getPendingTxsForChains (
36
- chains : string [ ] ,
37
- multiProvider : MultiProvider ,
38
- ) : Promise < SafeStatus [ ] > {
39
- const txs : SafeStatus [ ] = [ ] ;
40
- await Promise . all (
41
- chains . map ( async ( chain ) => {
42
- if ( ! safes [ chain ] ) {
43
- console . error ( chalk . red . bold ( `No safe found for ${ chain } ` ) ) ;
44
- return ;
45
- }
46
-
47
- if ( chain === 'endurance' ) {
48
- console . info (
49
- chalk . gray . italic (
50
- `Skipping chain ${ chain } as it does not have a functional safe API` ,
51
- ) ,
52
- ) ;
53
- return ;
54
- }
55
-
56
- let safeSdk , safeService ;
57
- try {
58
- ( { safeSdk, safeService } = await getSafeAndService (
59
- chain ,
60
- multiProvider ,
61
- safes [ chain ] ,
62
- ) ) ;
63
- } catch ( error ) {
64
- console . warn (
65
- chalk . yellow (
66
- `Skipping chain ${ chain } as there was an error getting the safe service: ${ error } ` ,
67
- ) ,
68
- ) ;
69
- return ;
70
- }
71
-
72
- const threshold = await safeSdk . getThreshold ( ) ;
73
- const pendingTxs = await safeService . getPendingTransactions ( safes [ chain ] ) ;
74
- if ( pendingTxs . results . length === 0 ) {
75
- return ;
76
- }
77
-
78
- const balance = await safeSdk . getBalance ( ) ;
79
- const nativeToken = await multiProvider . getNativeToken ( chain ) ;
80
- const formattedBalance = formatUnits ( balance , nativeToken . decimals ) ;
81
-
82
- pendingTxs . results . forEach (
83
- ( { nonce, submissionDate, safeTxHash, confirmations } ) => {
84
- const confs = confirmations ?. length ?? 0 ;
85
- const status =
86
- confs >= threshold
87
- ? SafeTxStatus . READY_TO_EXECUTE
88
- : confs === 0
89
- ? SafeTxStatus . NO_CONFIRMATIONS
90
- : threshold - confs
91
- ? SafeTxStatus . ONE_AWAY
92
- : SafeTxStatus . PENDING ;
93
-
94
- txs . push ( {
95
- chain,
96
- nonce,
97
- submissionDate : new Date ( submissionDate ) . toDateString ( ) ,
98
- shortTxHash : `${ safeTxHash . slice ( 0 , 6 ) } ...${ safeTxHash . slice ( - 4 ) } ` ,
99
- fullTxHash : safeTxHash ,
100
- confs,
101
- threshold,
102
- status,
103
- balance : `${ Number ( formattedBalance ) . toFixed ( 5 ) } ${
104
- nativeToken . symbol
105
- } `,
106
- } ) ;
107
- } ,
108
- ) ;
109
- } ) ,
110
- ) ;
111
- return txs . sort (
112
- ( a , b ) => a . chain . localeCompare ( b . chain ) || a . nonce - b . nonce ,
113
- ) ;
114
- }
115
-
116
23
async function main ( ) {
117
24
const safeChains = Object . keys ( safes ) ;
118
25
configureRootLogger ( LogFormat . Pretty , LogLevel . Info ) ;
@@ -129,7 +36,7 @@ async function main() {
129
36
130
37
const chainsToCheck = chains || safeChains ;
131
38
if ( chainsToCheck . length === 0 ) {
132
- console . error ( 'No chains provided' ) ;
39
+ rootLogger . error ( 'No chains provided' ) ;
133
40
process . exit ( 1 ) ;
134
41
}
135
42
@@ -141,11 +48,16 @@ async function main() {
141
48
chainsToCheck ,
142
49
) ;
143
50
144
- const pendingTxs = await getPendingTxsForChains ( chainsToCheck , multiProvider ) ;
51
+ const pendingTxs = await getPendingTxsForChains (
52
+ chainsToCheck ,
53
+ multiProvider ,
54
+ safes ,
55
+ ) ;
145
56
if ( pendingTxs . length === 0 ) {
146
- console . info ( chalk . green ( 'No pending transactions found!' ) ) ;
57
+ rootLogger . info ( chalk . green ( 'No pending transactions found!' ) ) ;
147
58
process . exit ( 0 ) ;
148
59
}
60
+ // eslint-disable-next-line no-console
149
61
console . table ( pendingTxs , [
150
62
'chain' ,
151
63
'nonce' ,
@@ -161,7 +73,7 @@ async function main() {
161
73
( tx ) => tx . status === SafeTxStatus . READY_TO_EXECUTE ,
162
74
) ;
163
75
if ( executableTxs . length === 0 ) {
164
- console . info ( chalk . green ( 'No transactions to execute!' ) ) ;
76
+ rootLogger . info ( chalk . green ( 'No transactions to execute!' ) ) ;
165
77
process . exit ( 0 ) ;
166
78
}
167
79
@@ -171,23 +83,23 @@ async function main() {
171
83
} ) ;
172
84
173
85
if ( ! shouldExecute ) {
174
- console . info (
86
+ rootLogger . info (
175
87
chalk . blue (
176
88
`${ executableTxs . length } transactions available for execution` ,
177
89
) ,
178
90
) ;
179
91
process . exit ( 0 ) ;
180
92
}
181
93
182
- console . info ( chalk . blueBright ( 'Executing transactions...' ) ) ;
94
+ rootLogger . info ( chalk . blueBright ( 'Executing transactions...' ) ) ;
183
95
184
96
for ( const tx of executableTxs ) {
185
97
const confirmExecuteTx = await confirm ( {
186
98
message : `Execute transaction ${ tx . shortTxHash } on chain ${ tx . chain } ?` ,
187
99
default : false ,
188
100
} ) ;
189
101
if ( confirmExecuteTx ) {
190
- console . log (
102
+ rootLogger . info (
191
103
`Executing transaction ${ tx . shortTxHash } on chain ${ tx . chain } ` ,
192
104
) ;
193
105
try {
@@ -198,7 +110,7 @@ async function main() {
198
110
tx . fullTxHash ,
199
111
) ;
200
112
} catch ( error ) {
201
- console . error ( chalk . red ( `Error executing transaction: ${ error } ` ) ) ;
113
+ rootLogger . error ( chalk . red ( `Error executing transaction: ${ error } ` ) ) ;
202
114
return ;
203
115
}
204
116
}
@@ -210,6 +122,6 @@ async function main() {
210
122
main ( )
211
123
. then ( )
212
124
. catch ( ( e ) => {
213
- console . error ( e ) ;
125
+ rootLogger . error ( e ) ;
214
126
process . exit ( 1 ) ;
215
127
} ) ;
0 commit comments