#nullable enable namespace Managing.Application.Bots.Models { [GenerateSerializer] public class AgentGrainState { [Id(0)] public string AgentName { get; set; } = string.Empty; [Id(1)] public HashSet BotIds { get; set; } = new HashSet(); /// /// Tracks if a swap operation is currently in progress to prevent multiple simultaneous swaps /// [Id(2)] public bool IsSwapInProgress { get; set; } = false; /// /// Timestamp of the last swap operation to implement cooldown period /// [Id(3)] public DateTime? LastSwapTime { get; set; } = null; /// /// Cached balance data to reduce external API calls /// [Id(4)] public CachedBalanceData? CachedBalanceData { get; set; } = null; /// /// Total fees paid by this agent across all positions /// [Id(5)] public decimal TotalFees { get; set; } = 0; } /// /// Cached balance data to avoid repeated external API calls /// [GenerateSerializer] public class CachedBalanceData { /// /// When the balance was last fetched /// [Id(0)] public DateTime LastFetched { get; set; } = DateTime.UtcNow; /// /// The account name this balance data is for /// [Id(1)] public string AccountName { get; set; } = string.Empty; /// /// ETH balance in USD /// [Id(2)] public decimal EthValueInUsd { get; set; } = 0; /// /// USDC balance value /// [Id(3)] public decimal UsdcValue { get; set; } = 0; /// /// Whether the cached data is still valid (less than 1 minute old) /// public bool IsValid => DateTime.UtcNow - LastFetched < TimeSpan.FromMinutes(1.5); } /// /// Result of a balance check operation /// [GenerateSerializer] public class BalanceCheckResult { /// /// Whether the balance check was successful /// [Id(0)] public bool IsSuccessful { get; set; } /// /// The reason for failure if not successful /// [Id(1)] public BalanceCheckFailureReason FailureReason { get; set; } /// /// Additional details about the result /// [Id(2)] public string Message { get; set; } = string.Empty; /// /// Whether the bot should stop due to this result /// [Id(3)] public bool ShouldStopBot { get; set; } } /// /// Reasons why a balance check might fail /// public enum BalanceCheckFailureReason { None, InsufficientUsdcBelowMinimum, InsufficientUsdcForSwap, SwapInProgress, SwapCooldownActive, BalanceFetchError, SwapExecutionError, InsufficientEthBelowMinimum, BotsHaveOpenPositions } }