diff --git a/src/Managing.Application/ManageBot/RestartBotCommandHandler.cs b/src/Managing.Application/ManageBot/RestartBotCommandHandler.cs index 4aa96307..f9a39432 100644 --- a/src/Managing.Application/ManageBot/RestartBotCommandHandler.cs +++ b/src/Managing.Application/ManageBot/RestartBotCommandHandler.cs @@ -1,4 +1,5 @@ using Managing.Application.Abstractions; +using Managing.Application.Abstractions.Services; using Managing.Application.ManageBot.Commands; using MediatR; using static Managing.Common.Enums; @@ -8,10 +9,14 @@ namespace Managing.Application.ManageBot public class RestartBotCommandHandler : IRequestHandler { private readonly IBotService _botService; + private readonly IAccountService _accountService; + private readonly ITradingService _tradingService; - public RestartBotCommandHandler(IBotService botService) + public RestartBotCommandHandler(IBotService botService, IAccountService accountService, ITradingService tradingService) { _botService = botService; + _accountService = accountService; + _tradingService = tradingService; } public async Task Handle(RestartBotCommand request, CancellationToken cancellationToken) @@ -37,6 +42,24 @@ namespace Managing.Application.ManageBot "You cannot restart this bot while you have multiple strategies on the same ticker."); } + // Get bot configuration to check account initialization status + var botConfig = await _botService.GetBotConfig(request.Identifier); + if (botConfig == null) + { + throw new InvalidOperationException($"Could not retrieve configuration for bot {request.Identifier}"); + } + + // Get account to check GMX initialization status + var account = await _accountService.GetAccount(botConfig.AccountName, true, true); + if (account.Exchange == TradingExchanges.GmxV2 && !account.IsGmxInitialized) + { + var initResult = await _tradingService.InitPrivyWallet(account.Key, TradingExchanges.GmxV2); + if (!initResult.Success) + { + throw new InvalidOperationException($"Failed to initialize GMX wallet: {initResult.Error}"); + } + } + return await _botService.RestartBot(request.Identifier); } } diff --git a/src/Managing.Application/ManageBot/StartBotCommandHandler.cs b/src/Managing.Application/ManageBot/StartBotCommandHandler.cs index ac26d199..36e606c0 100644 --- a/src/Managing.Application/ManageBot/StartBotCommandHandler.cs +++ b/src/Managing.Application/ManageBot/StartBotCommandHandler.cs @@ -14,13 +14,15 @@ namespace Managing.Application.ManageBot private readonly IAccountService _accountService; private readonly IGrainFactory _grainFactory; private readonly IBotService _botService; + private readonly ITradingService _tradingService; public StartBotCommandHandler( - IAccountService accountService, IGrainFactory grainFactory, IBotService botService) + IAccountService accountService, IGrainFactory grainFactory, IBotService botService, ITradingService tradingService) { _accountService = accountService; _grainFactory = grainFactory; _botService = botService; + _tradingService = tradingService; } public async Task Handle(StartBotCommand request, CancellationToken cancellationToken) @@ -79,6 +81,16 @@ namespace Managing.Application.ManageBot } } + // Check GMX initialization status for GMX V2 accounts + if (account.Exchange == TradingExchanges.GmxV2 && !account.IsGmxInitialized) + { + var initResult = await _tradingService.InitPrivyWallet(account.Key, TradingExchanges.GmxV2); + if (!initResult.Success) + { + throw new InvalidOperationException($"Failed to initialize GMX wallet: {initResult.Error}"); + } + } + Balance usdcBalance = null; // For other exchanges, keep the original USDC balance check if (account.Exchange != TradingExchanges.Evm && account.Exchange != TradingExchanges.GmxV2) diff --git a/src/Managing.Application/ManageBot/StartCopyTradingCommandHandler.cs b/src/Managing.Application/ManageBot/StartCopyTradingCommandHandler.cs index 35caac19..399ffd5d 100644 --- a/src/Managing.Application/ManageBot/StartCopyTradingCommandHandler.cs +++ b/src/Managing.Application/ManageBot/StartCopyTradingCommandHandler.cs @@ -19,16 +19,18 @@ namespace Managing.Application.ManageBot private readonly IBotService _botService; private readonly IKaigenService _kaigenService; private readonly IEvmManager _evmManager; + private readonly ITradingService _tradingService; public StartCopyTradingCommandHandler( IAccountService accountService, IGrainFactory grainFactory, IBotService botService, - IKaigenService kaigenService, IEvmManager evmManager) + IKaigenService kaigenService, IEvmManager evmManager, ITradingService tradingService) { _accountService = accountService; _grainFactory = grainFactory; _botService = botService; _kaigenService = kaigenService; _evmManager = evmManager; + _tradingService = tradingService; } public async Task Handle(StartCopyTradingCommand request, CancellationToken cancellationToken) @@ -113,6 +115,16 @@ namespace Managing.Application.ManageBot } } + // Check GMX initialization status for GMX V2 accounts + if (account.Exchange == TradingExchanges.GmxV2 && !account.IsGmxInitialized) + { + var initResult = await _tradingService.InitPrivyWallet(account.Key, TradingExchanges.GmxV2); + if (!initResult.Success) + { + throw new InvalidOperationException($"Failed to initialize GMX wallet: {initResult.Error}"); + } + } + Balance usdcBalance = null; // For other exchanges, keep the original USDC balance check if (account.Exchange != TradingExchanges.Evm && account.Exchange != TradingExchanges.GmxV2) diff --git a/src/Managing.Core/Exceptions/CustomExceptions.cs b/src/Managing.Core/Exceptions/CustomExceptions.cs index 697d406a..48a23c85 100644 --- a/src/Managing.Core/Exceptions/CustomExceptions.cs +++ b/src/Managing.Core/Exceptions/CustomExceptions.cs @@ -93,7 +93,7 @@ public class InsufficientFundsException : Exception /// public string UserMessage { get; } - public InsufficientFundsException(string errorMessage, InsufficientFundsType errorType) + public InsufficientFundsException(string errorMessage, InsufficientFundsType errorType) : base(errorMessage) { ErrorType = errorType; @@ -104,31 +104,31 @@ public class InsufficientFundsException : Exception { return errorType switch { - InsufficientFundsType.InsufficientEth => + InsufficientFundsType.InsufficientEth => "❌ Insufficient ETH for Gas Fees\n" + "Your wallet doesn't have enough ETH to pay for transaction gas fees.\n" + "Please add ETH to your wallet and try again.", - - // InsufficientFundsType.InsufficientAllowance => - // "❌ Insufficient Token Allowance\n" + - // "The trading contract doesn't have permission to spend your tokens.\n" + - // "Please approve token spending in your wallet and try again.", - - InsufficientFundsType.InsufficientAllowance => - "❌ High Network Fee\n" + - "The gas fee for this position is too high.\n" + - "Position opening rejected.", - InsufficientFundsType.InsufficientBalance => + InsufficientFundsType.InsufficientAllowance => + "❌ Insufficient Token Allowance\n" + + "The trading contract doesn't have permission to spend your tokens, or you don't have enough ETH in your wallet to cover the required amount when using GMX SDK.\n" + + "Please approve token spending in your wallet and ensure you have sufficient ETH for the transaction, then try again.", + + // InsufficientFundsType.InsufficientAllowance => + // "❌ High Network Fee\n" + + // "The gas fee for this position is too high.\n" + + // "Position opening rejected.", + + InsufficientFundsType.InsufficientBalance => "❌ Insufficient Token Balance\n" + "Your wallet doesn't have enough tokens for this trade.\n" + "Please add more tokens to your wallet and try again.", - InsufficientFundsType.HighNetworkFee => + InsufficientFundsType.HighNetworkFee => "❌ High Network Fee\n" + "The gas fee for this position is too high.\n" + "Position opening rejected.", - + _ => "❌ Transaction Failed\n" + "The transaction failed due to insufficient funds.\n" + "Please check your wallet balance and try again." @@ -145,17 +145,17 @@ public enum InsufficientFundsType /// Not enough ETH for gas fees /// InsufficientEth, - + /// /// Token allowance is insufficient (ERC20: transfer amount exceeds allowance) /// InsufficientAllowance, - + /// /// Token balance is insufficient /// InsufficientBalance, - + /// /// General insufficient funds error ///