@@ -84,6 +84,30 @@ function ensurePersona(wallet) {
8484 return walletProfiles [ wallet . address ] ;
8585}
8686
87+ // === NEW: Inactive Wallet Management ===
88+ const inactiveFile = "inactive.json" ;
89+ let inactiveWallets = new Set ( ) ;
90+
91+ function loadInactive ( ) {
92+ if ( fs . existsSync ( inactiveFile ) ) {
93+ try {
94+ inactiveWallets = new Set ( JSON . parse ( fs . readFileSync ( inactiveFile , "utf-8" ) ) ) ;
95+ console . log ( chalk . gray ( `📂 Loaded ${ inactiveWallets . size } inactive wallets` ) ) ;
96+ } catch ( e ) {
97+ console . error ( "❌ Failed parsing inactive.json, starting empty" ) ;
98+ inactiveWallets = new Set ( ) ;
99+ }
100+ }
101+ }
102+
103+ function saveInactive ( ) {
104+ try {
105+ fs . writeFileSync ( inactiveFile , JSON . stringify ( [ ...inactiveWallets ] , null , 2 ) ) ;
106+ } catch ( e ) {
107+ console . error ( "❌ Failed saving inactive.json:" , e . message ) ;
108+ }
109+ }
110+
87111// --- Dynamic Log File Management (Daily Rotation) ---
88112// This function returns the log file path for the current day.
89113function getLogFile ( ) {
@@ -177,6 +201,25 @@ function isWithinActiveHours(profile) {
177201 return nowUTC >= profile . activeHours [ 0 ] && nowUTC <= profile . activeHours [ 1 ] ;
178202}
179203
204+ // === NEW: Active Hours Check ===
205+ function checkActive ( wallet , profile ) {
206+ if ( isWithinActiveHours ( profile ) ) {
207+ if ( inactiveWallets . has ( wallet . address ) ) {
208+ inactiveWallets . delete ( wallet . address ) ;
209+ saveInactive ( ) ;
210+ console . log ( chalk . green ( `✅ Wallet ${ wallet . address } re-activated` ) ) ;
211+ }
212+ return true ;
213+ } else {
214+ if ( ! inactiveWallets . has ( wallet . address ) ) {
215+ inactiveWallets . add ( wallet . address ) ;
216+ saveInactive ( ) ;
217+ console . log ( chalk . gray ( `🛌 Wallet ${ wallet . address } marked inactive` ) ) ;
218+ }
219+ return false ;
220+ }
221+ }
222+
180223async function sendTx ( wallet , provider , profile , url ) {
181224 try {
182225 if ( Math . random ( ) < profile . idleBias ) {
@@ -307,8 +350,22 @@ async function safeSendTx(wallet, provider, profile, url) {
307350 }
308351}
309352
353+ // === NEW: Refresh inactive wallets every 30 minutes ===
354+ setInterval ( ( ) => {
355+ console . log ( chalk . cyan ( "🔄 Refreshing inactive wallets..." ) ) ;
356+ for ( const addr of [ ...inactiveWallets ] ) {
357+ const profile = walletProfiles [ addr ] ;
358+ if ( profile && isWithinActiveHours ( profile ) ) {
359+ inactiveWallets . delete ( addr ) ;
360+ console . log ( chalk . green ( `🌅 Wallet ${ addr } is now inside active hours` ) ) ;
361+ }
362+ }
363+ saveInactive ( ) ;
364+ } , 30 * 60 * 1000 ) ;
365+
310366async function loop ( ) {
311- loadPersonas ( ) ; // Load personas at the start of the loop
367+ loadPersonas ( ) ;
368+ loadInactive ( ) ;
312369 while ( true ) {
313370 // === NEW LOGIC: Retry loop for RPC connection ===
314371 let provider = null ;
@@ -329,11 +386,9 @@ async function loop() {
329386 const wallet = new ethers . Wallet ( key , provider ) ;
330387 const profile = ensurePersona ( wallet ) ;
331388
332- // Check if the wallet is within its active hours
333- if ( ! isWithinActiveHours ( profile ) ) {
334- const sleepSec = 600 + Math . floor ( Math . random ( ) * 600 ) ; // 10–20 min idle
335- console . log ( chalk . gray ( `🛌 Wallet ${ wallet . address } is outside active hours, sleeping ${ sleepSec } s` ) ) ;
336- await randomDelay ( sleepSec , sleepSec ) ;
389+ // === NEW: Main loop modification ===
390+ if ( ! checkActive ( wallet , profile ) ) {
391+ await randomDelay ( 10 , 15 ) ; // just a short pause
337392 continue ;
338393 }
339394
0 commit comments