Files
managing-apps/src/Managing.Application/ManageBot/StartBotCommandHandler.cs
2025-08-14 18:08:31 +07:00

77 lines
2.9 KiB
C#

using Managing.Application.Abstractions.Grains;
using Managing.Application.Abstractions.Services;
using Managing.Application.ManageBot.Commands;
using Managing.Common;
using MediatR;
using static Managing.Common.Enums;
namespace Managing.Application.ManageBot
{
public class StartBotCommandHandler : IRequestHandler<StartBotCommand, BotStatus>
{
private readonly IAccountService _accountService;
private readonly IGrainFactory _grainFactory;
public StartBotCommandHandler(
IAccountService accountService, IGrainFactory grainFactory)
{
_accountService = accountService;
_grainFactory = grainFactory;
}
public async Task<BotStatus> Handle(StartBotCommand request, CancellationToken cancellationToken)
{
// Validate the configuration
if (request.Config == null)
{
throw new ArgumentException("Bot configuration is required");
}
if (request.Config.Scenario == null || !request.Config.Scenario.Indicators.Any())
{
throw new InvalidOperationException(
"Scenario or indicators not loaded properly in constructor. This indicates a configuration error.");
}
if (request.Config.BotTradingBalance <= Constants.GMX.Config.MinimumPositionAmount)
{
throw new ArgumentException(
$"Bot trading balance must be greater than {Constants.GMX.Config.MinimumPositionAmount}");
}
var account = await _accountService.GetAccount(request.Config.AccountName, true, true);
if (account == null)
{
throw new Exception($"Account {request.Config.AccountName} not found");
}
var usdcBalance = account.Balances.FirstOrDefault(b => b.TokenName == Ticker.USDC.ToString());
if (usdcBalance == null ||
usdcBalance.Value < Constants.GMX.Config.MinimumPositionAmount ||
usdcBalance.Value < request.Config.BotTradingBalance)
{
throw new Exception($"Account {request.Config.AccountName} has no USDC balance or not enough balance");
}
try
{
var botGrain = _grainFactory.GetGrain<ILiveTradingBotGrain>(Guid.NewGuid());
await botGrain.CreateAsync(request.Config, request.User);
// Only start the bot if createOnly is false
if (!request.CreateOnly)
{
await botGrain.StartAsync();
}
}
catch (Exception ex)
{
throw new Exception($"Failed to start bot: {ex.Message}, {ex.StackTrace}");
}
return request.CreateOnly ? BotStatus.Saved : BotStatus.Running;
}
}
}