
    [i-                        d Z ddlZddlZddlZddlZddlmZmZmZ ddl	m	Z	m
Z
mZ ddlmZ ddlZddlmZmZmZmZ dZdZd	Zd
Ze G d d                      Ze G d d                      Z	 	 ddee         dej        dee         dee         def
dZdej        dee         fdZdej        fdZ dej        dee         fdZ!dej        dee         fdZ"dS )a  
LuckySt Syndicate - Game Scheduler with Base On-Chain Commitment

Schedules a LuckBot Trader to trade a list of specific games in the next 24 hours.
The schedule is committed to Base as an immutable self-transfer transaction,
then stored in Redis for the execution engine to pick up and deploy at game time.

Flow:
1. User provides list of games (tickers + start times + optional config)
2. Schedule commitment is written to Base (calldata = JSON schedule)
3. Schedule entries stored in Redis sorted set (score = start timestamp)
4. Background poller checks Redis every 30s and deploys instances at game time
5. When session ends, on-chain report is generated (via mm_core report hook)
    N)	dataclassfieldasdict)datetimetimezone	timedelta)Optional)write_report_to_chainLUCKYST_BUILDER_SUFFIXBASE_RPC_URLBASE_CHAIN_IDzluckyst:schedule:pendingzluckyst:schedule:meta:zluckyst:schedule:activezluckyst:schedule:donec                   j    e Zd ZU dZee         ed<   eed<   dZee         ed<   dZ	e
ed<   dZeed	<   dS )
	GameEntryzA single game to be traded.markets
start_timeN	stop_time   contract_sizeFhigher_first)__name__
__module____qualname____doc__liststr__annotations__r   r	   r   intr   bool     (/app/agentic/syndicate/game_scheduler.pyr   r   .   se         %%#YOOO#Ix}###M3L$r    r   c                       e Zd ZU dZeed<    ee          Zee	         ed<   dZ
eed<   dZee         ed<   dZeed	<   d
efdZeded
d fd            ZdS )ScheduleCommitmentz Full schedule committed to Base.schedule_id)default_factorygames 
created_atNbase_txauthor_addressreturnc                 H    t          j        t          |           d          S )N   )indent)jsondumpsr   )selfs    r!   to_jsonzScheduleCommitment.to_jsonA   s    z&,,q1111r    rawc           
         t          j        |           }d |                    dg           D             }t          |d         ||                    dd          |                    d          |                    dd                    S )	Nc                 &    g | ]}t          d i |S )r   )r   ).0gs     r!   
<listcomp>z0ScheduleCommitment.from_json.<locals>.<listcomp>G   s"    ???AQ???r    r&   r$   r(   r'   r)   r*   )r$   r&   r(   r)   r*   )r/   loadsgetr#   )r3   datar&   s      r!   	from_jsonzScheduleCommitment.from_jsonD   s    z#??'2)>)>???!]+xxb11HHY''88$4b99
 
 
 	
r    )r   r   r   r   r   r   r   r   r&   r   r(   r)   r	   r*   r2   staticmethodr<   r   r    r!   r#   r#   8   s         **"U4888E4	?888J!GXc]!!!NC2 2 2 2 2 	
s 	
3 	
 	
 	
 \	
 	
 	
r    r#   r&   redis_clientbase_addressbase_keyr+   c                 x  K   t          t          j                              dd         }t          j        t
          j                  }g }| D ]r}t          |d         |d         |                    d          |                    dd          |                    dd	          
          }|	                    |           st          |||                                |pd          }	|r|r	 |	                                                    d          }
d|
z   }t          |||           d{V }|j        r+|j        r$|j        |	_        t%          d|j                    nt%          d|j                    n)# t(          $ r}t%          d|            Y d}~nd}~ww xY wt+          |          D ]\  }}	 t          j        |j                  }|                                }n$# t(          $ r |                                }Y nw xY w| d| }|||j        |j        |j        |j        |j        d|	j        d	}|                    t<          ||i           |                    t@           | tC          j"        |                     |                    t@           | |	                                           |	S )a  
    Create a game schedule, commit to Base, and store in Redis.

    Args:
        games: List of game dicts with keys: markets, start_time, stop_time,
               contract_size, higher_first
        redis_client: Redis connection
        base_address: Base address for on-chain commitment (optional)
        base_key: Private key for signing (optional)

    Returns:
        ScheduleCommitment with schedule_id and optional base_tx
    N   r   r   r   r   r   r   F)r   r   r   r   r   r'   )r$   r&   r(   r*   zutf-8   u    ✓ Schedule committed to Base: u   ⚠️ Base commit failed: u   ⚠️ Base commit error: :pending)	r$   
game_indexr   r   r   r   r   statusr)   )#r   uuiduuid4r   nowr   utcr   r:   appendr#   	isoformatr2   encoder
   successtx_hashr)   printerror	Exception	enumeratefromisoformatr   	timestampr   r   r   r   zaddSCHEDULE_SETsetSCHEDULE_METAr/   r0   )r&   r>   r?   r@   r$   rJ   game_entriesr7   entry
commitmentschedule_bytes
chain_dataresulteigamestart_dtstart_tsgame_id	game_metas                       r!   create_schedulerh   U   s     & djll##BQB'K
,x|
$
$CL # #iLeeK((%%33~u55
 
 
 	E""""#==??#)r	  J  4 4	4'//1188AAN >1J0X|TTTTTTTTF~ D&. D%+^
"IIIJJJJBFLBBCCC 	4 	4 	42q2233333333	4 \** M M4	'-do>>H))++HH 	' 	' 	'}}HHH	' !&&1&&&|/!/ -!)

 

	 	,((;<<<M4744dj6K6KLLLL 4{44j6H6H6J6JKKKs+   ,BE9 9
FFF7-G%%HHc           	        K   t          j        t          j                                                  }g }|                     t          d|          }|D ]}t          |t                    r|	                                n|}| 
                    t           |           }|s|                     t          |           jt          j        t          |t                    r|n|	                                          }|
                    d          dk    r|                     t          |           	  ||d         |
                    dd          |
                    dd          	           d
{V }	d|d<   |	|d<   t          j        t          j                                                  |d<   |                     t           | t          j        |                     |                     t(          |           |                     t          |           |                    |           t-          d| d|	            |
                    d          rm	 t          j        |d                   }
|
                                }|                     dt          j        ||	d          |i           n# t2          $ r Y nw xY wq# t2          $ r}t-          d| d|            d|d<   t          |          |d<   |                     t           | t          j        |                     |                     t          |           Y d
}~d
}~ww xY w|S )at  
    Check for games that should start now and deploy them.

    Called periodically (every 30s) by a background task.

    Args:
        redis_client: Redis connection
        deploy_fn: async fn(markets, contract_size, higher_first) -> instance_id
                   Should call the /terminal/auto/deploy API endpoint

    Returns:
        List of deployed game IDs
    -infrG   rE   r   r   r   r   F)r   r   r   Nrunninginstance_iddeployed_atu   ✓ Scheduled game z deployed as instance #r   luckyst:schedule:stops)rf   rl   u   ⚠️ Failed to deploy game : failedrR   )r   rJ   r   rK   rV   zrangebyscorerX   
isinstancebytesdecoder:   rZ   zremr/   r9   r   rM   rY   r0   saddSCHEDULE_ACTIVErL   rQ   rU   rW   rS   )r>   	deploy_fnrJ   deployed	due_gamesgame_id_rawrf   meta_rawmetarl   stop_dtstop_tsra   s                r!    check_and_deploy_scheduled_gamesr      s     " ,x|
$
$
.
.
0
0CH **<EEI  45 45*4[%*H*HY+$$&&&k  ##}$?g$?$?@@ 	lG444zj3&?&?V((X__EVEVWW88H**lG444$	5 )	Y"hh::!XXne<<! ! !      K 'DN"-D"*,x|"<"<"F"F"H"HD8w88$*T:J:JKKKow777 lG444OOG$$$UUUUUVVV xx$$ &4T+5FGGG%//11G %%&>
w{#S#STTV]A     !   D  	5 	5 	5@'@@Q@@AAA%DNFFDM8w88$*T:J:JKKKlG44444444	5 Os?   0D%KAJ21K2
J?<K>J??K
MA8MMc                   K   t          j        t          j                                                  }|                     dd|          }|D ]}t          j        t          |t                    r|n|
                                          }|d         }|d         }	  ||           d{V  t          d| d|            n,# t          $ r}t          d| d	|            Y d}~nd}~ww xY w|                     d|           |                     t           |           }	|	rt          j        t          |	t                    r|	n|	
                                          }
d
|
d<   t          j        t          j                                                  |
d<   |                     t           | t          j        |
                     |                     t(          |           |                     t,          |           dS )z
    Check for games that should stop now and send stop commands.

    Args:
        redis_client: Redis connection
        stop_fn: async fn(instance_id) -> None
    rn   rj   rf   rl   Nu   ✓ Scheduled stop for game z, instance #u   ⚠️ Failed to stop game ro   	completedrG   
stopped_at)r   rJ   r   rK   rV   rq   r/   r9   rr   r   rt   rQ   rS   ru   r:   rZ   rM   rY   r0   sremrw   rv   SCHEDULE_DONE)r>   stop_fnrJ   	due_stops	entry_rawr\   rf   rl   ra   r|   r}   s              r!   check_and_stop_scheduled_gamesr      s#      ,x|
$
$
.
.
0
0C**+CVSQQI 6 6	

9c(B(BZ99	HXHXHZHZ[[	"M*	@'+&&&&&&&&&SSSkSSTTTT 	@ 	@ 	@>>>1>>????????	@ 	2I>>>  ##}$?g$?$?@@ 	6:*Xs*C*CZhhIZIZ[[D(DN!)hl!;!;!E!E!G!GD8w88$*T:J:JKKKow777mW555+6 6s   &C
C-C((C-c                    |                      t          ddd          }g }|D ]\  }}t          |t                    r|                                n|}|                     t           |           }|rWt          j        t          |t                    r|n|                                          }||d<   |
                    |           |S )z!List all pending scheduled games.r   T)
withscoresscheduled_start_ts)zrangerX   rr   rs   rt   r:   rZ   r/   r9   r   rL   )r>   game_idsresultsr{   scorerf   r|   r}   s           r!   list_pending_gamesr   *  s    ""<B4"HHHG& ! !U*4[%*H*HY+$$&&&k##}$?g$?$?@@ 	!:*Xs*C*CZhhIZIZ[[D).D%&NN4   Nr    c           	      ~   |                      t                    }g }|D ]}t          |t                    r|                                n|}|                     t           |           }|rP|                    t          j	        t          |t                    r|n|                                                     |S )z+List all currently running scheduled games.)smembersrw   rr   rs   rt   r:   rZ   rL   r/   r9   r   )r>   r   r   r{   rf   r|   s         r!   list_active_gamesr   8  s    $$_55HG e e*4[%*H*HY+$$&&&k##}$?g$?$?@@ 	eNN4:*Xs2K2K&bhhQYQ`Q`QbQbccdddNr    )NN)#r   osr/   rH   asynciodataclassesr   r   r   r   r   r   typingr	   redisagentic.syndicate.chain_writerr
   r   r   r   rX   rZ   rw   r   r   r#   r   dictRedisr   rh   r   r   r   r   r   r    r!   <module>r      sZ    
			    0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2                   *(+'         
 
 
 
 
 
 
 
> #'"	T T:T+T 3-T sm	T
 T T T TvM+M 
#YM M M M`#6+#6 #6 #6 #6TU[ T$Z    	EK 	DJ 	 	 	 	 	 	r    