From ff74296c269ee6684534f5a108ba05d34e114859 Mon Sep 17 00:00:00 2001 From: cryptooda Date: Sun, 12 Oct 2025 16:08:12 +0700 Subject: [PATCH] Fix restart/start if not account with the first account of the user --- .../Grains/ILiveTradingBotGrain.cs | 5 +++ .../Bots/Grains/LiveTradingBotGrain.cs | 13 ++++++++ .../ManageBot/BotService.cs | 32 +++++++++++++++++-- .../ManageBot/StartBotCommandHandler.cs | 18 ++++++++--- 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/src/Managing.Application.Abstractions/Grains/ILiveTradingBotGrain.cs b/src/Managing.Application.Abstractions/Grains/ILiveTradingBotGrain.cs index f96cd6fe..313d7df8 100644 --- a/src/Managing.Application.Abstractions/Grains/ILiveTradingBotGrain.cs +++ b/src/Managing.Application.Abstractions/Grains/ILiveTradingBotGrain.cs @@ -53,4 +53,9 @@ public interface ILiveTradingBotGrain : IGrainWithGuidKey /// Returns true if there are open positions, false otherwise /// Task HasOpenPositionsAsync(); + + /// + /// Gets the user who owns this bot + /// + Task GetUserAsync(); } \ No newline at end of file diff --git a/src/Managing.Application/Bots/Grains/LiveTradingBotGrain.cs b/src/Managing.Application/Bots/Grains/LiveTradingBotGrain.cs index 0a84a60c..a49a0e54 100644 --- a/src/Managing.Application/Bots/Grains/LiveTradingBotGrain.cs +++ b/src/Managing.Application/Bots/Grains/LiveTradingBotGrain.cs @@ -1006,4 +1006,17 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable return true; } } + + /// + /// Gets the user who owns this bot + /// + public Task GetUserAsync() + { + if (_state.State.User == null) + { + throw new InvalidOperationException($"Bot '{_state.State.Config?.Name}' (ID: {_state.State.Identifier}) has no user information."); + } + + return Task.FromResult(_state.State.User); + } } \ No newline at end of file diff --git a/src/Managing.Application/ManageBot/BotService.cs b/src/Managing.Application/ManageBot/BotService.cs index 5b7f7805..5778b3f3 100644 --- a/src/Managing.Application/ManageBot/BotService.cs +++ b/src/Managing.Application/ManageBot/BotService.cs @@ -109,9 +109,35 @@ namespace Managing.Application.ManageBot // Check balances for EVM/GMX V2 bots before starting/restarting var botConfig = await botGrain.GetConfiguration(); - var account = await ServiceScopeHelpers.WithScopedService( - _scopeFactory, - async accountService => await accountService.GetAccount(botConfig.AccountName, true, true)); + + Account account; + if (string.IsNullOrEmpty(botConfig.AccountName)) + { + // Fallback: Get the first account for the user + var user = await botGrain.GetUserAsync(); + + account = await ServiceScopeHelpers.WithScopedService( + _scopeFactory, + async accountService => + { + var userAccounts = await accountService.GetAccountsByUserAsync(user, true, true); + var firstAccount = userAccounts.FirstOrDefault(); + if (firstAccount == null) + { + throw new InvalidOperationException($"User '{user.Name}' has no accounts configured."); + } + return firstAccount; + }); + + _tradingBotLogger.LogInformation("Bot '{BotName}' (ID: {BotId}) using fallback account '{AccountName}' for user '{UserName}'", + botConfig.Name, identifier, account.Name, user.Name); + } + else + { + account = await ServiceScopeHelpers.WithScopedService( + _scopeFactory, + async accountService => await accountService.GetAccount(botConfig.AccountName, true, true)); + } if (account.Exchange == TradingExchanges.Evm || account.Exchange == TradingExchanges.GmxV2) { diff --git a/src/Managing.Application/ManageBot/StartBotCommandHandler.cs b/src/Managing.Application/ManageBot/StartBotCommandHandler.cs index 0f41e91f..63484fb4 100644 --- a/src/Managing.Application/ManageBot/StartBotCommandHandler.cs +++ b/src/Managing.Application/ManageBot/StartBotCommandHandler.cs @@ -43,11 +43,21 @@ namespace Managing.Application.ManageBot $"Bot trading balance must be greater than {Constants.GMX.Config.MinimumPositionAmount}"); } - var account = await _accountService.GetAccount(request.Config.AccountName, true, true); - - if (account == null) + Account account; + if (string.IsNullOrEmpty(request.Config.AccountName)) { - throw new Exception($"Account {request.Config.AccountName} not found"); + // Fallback: Get the first account for the user + var userAccounts = await _accountService.GetAccountsByUserAsync(request.User, true, true); + var firstAccount = userAccounts.FirstOrDefault(); + if (firstAccount == null) + { + throw new InvalidOperationException($"User '{request.User.Name}' has no accounts configured."); + } + account = firstAccount; + } + else + { + account = await _accountService.GetAccount(request.Config.AccountName, true, true); } // Check balances for EVM/GMX V2 accounts before starting