diff --git a/src/Managing.Application.Abstractions/Services/IKaigenService.cs b/src/Managing.Application.Abstractions/Services/IKaigenService.cs
index 07ce632..d8611f4 100644
--- a/src/Managing.Application.Abstractions/Services/IKaigenService.cs
+++ b/src/Managing.Application.Abstractions/Services/IKaigenService.cs
@@ -1,3 +1,5 @@
+using Managing.Domain.Users;
+
namespace Managing.Application.Abstractions.Services;
public interface IKaigenService
@@ -5,16 +7,16 @@ public interface IKaigenService
///
/// Debits user credits for a backtest operation
///
- /// The username to debit
+ /// The user to debit
/// The amount to debit
/// The request ID for tracking
- Task DebitUserCreditsAsync(string userName, decimal debitAmount);
+ Task DebitUserCreditsAsync(User user, decimal debitAmount);
///
/// Refunds user credits if debit operation fails
///
/// The original request ID from debit operation
- /// The username to refund
+ /// The user to refund
/// True if refund was successful
- Task RefundUserCreditsAsync(string requestId, string userName);
+ Task RefundUserCreditsAsync(string requestId, User user);
}
\ No newline at end of file
diff --git a/src/Managing.Application/Backtesting/Backtester.cs b/src/Managing.Application/Backtesting/Backtester.cs
index 2a76e4d..9197bf4 100644
--- a/src/Managing.Application/Backtesting/Backtester.cs
+++ b/src/Managing.Application/Backtesting/Backtester.cs
@@ -92,7 +92,7 @@ namespace Managing.Application.Backtesting
{
try
{
- creditRequestId = await _kaigenService.DebitUserCreditsAsync(user.Name, 3);
+ creditRequestId = await _kaigenService.DebitUserCreditsAsync(user, 3);
_logger.LogInformation("Successfully debited credits for user {UserName} with request ID {RequestId}",
user.Name, creditRequestId);
}
@@ -127,7 +127,7 @@ namespace Managing.Application.Backtesting
{
try
{
- var refundSuccess = await _kaigenService.RefundUserCreditsAsync(creditRequestId, user.Name);
+ var refundSuccess = await _kaigenService.RefundUserCreditsAsync(creditRequestId, user);
if (refundSuccess)
{
_logger.LogInformation("Successfully refunded credits for user {UserName} after backtest failure", user.Name);
diff --git a/src/Managing.Infrastructure.Web3/Services/KaigenService.cs b/src/Managing.Infrastructure.Web3/Services/KaigenService.cs
index 9a53a49..73dcd14 100644
--- a/src/Managing.Infrastructure.Web3/Services/KaigenService.cs
+++ b/src/Managing.Infrastructure.Web3/Services/KaigenService.cs
@@ -1,6 +1,7 @@
using System.Net.Http.Json;
using System.Text.Json;
using Managing.Application.Abstractions.Services;
+using Managing.Domain.Users;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Nethereum.Signer;
@@ -56,22 +57,15 @@ public class KaigenService : IKaigenService
}
}
- public async Task DebitUserCreditsAsync(string userName, decimal debitAmount)
+ public async Task DebitUserCreditsAsync(User user, decimal debitAmount)
{
try
{
+ var walletAddress = GetUserWalletAddress(user);
var requestId = Guid.NewGuid().ToString();
- // Create the payload for signing
- var payload = new
- {
- RequestId = requestId,
- UserName = userName,
- DebitAmount = debitAmount
- };
-
// Create the message to sign (concatenate the values)
- var message = $"{requestId}{userName}{debitAmount}";
+ var message = $"{requestId}{walletAddress}{debitAmount}";
// Sign the message
var signature = SignMessage(message, _settings.PrivateKey);
@@ -80,13 +74,13 @@ public class KaigenService : IKaigenService
var requestPayload = new
{
requestId = requestId,
- userName = userName,
+ walletAddress = walletAddress,
debitAmount = debitAmount,
signature = signature
};
- _logger.LogInformation("Debiting {Amount} credits for user {UserName} with request ID {RequestId}",
- debitAmount, userName, requestId);
+ _logger.LogInformation("Debiting {Amount} credits for user {UserName} (wallet: {WalletAddress}) with request ID {RequestId}",
+ debitAmount, user.Name, walletAddress, requestId);
var response = await _httpClient.PutAsJsonAsync(
$"{_settings.BaseUrl}{_settings.DebitEndpoint}",
@@ -102,24 +96,26 @@ public class KaigenService : IKaigenService
}
var result = await response.Content.ReadFromJsonAsync(_jsonOptions);
- _logger.LogInformation("Successfully debited {Amount} credits for user {UserName}",
- debitAmount, userName);
+ _logger.LogInformation("Successfully debited {Amount} credits for user {UserName} (wallet: {WalletAddress})",
+ debitAmount, user.Name, walletAddress);
return requestId;
}
catch (Exception ex)
{
- _logger.LogError(ex, "Error debiting credits for user {UserName}", userName);
+ _logger.LogError(ex, "Error debiting credits for user {UserName}", user.Name);
throw;
}
}
- public async Task RefundUserCreditsAsync(string requestId, string userName)
+ public async Task RefundUserCreditsAsync(string requestId, User user)
{
try
{
+ var walletAddress = GetUserWalletAddress(user);
+
// Create the message to sign (concatenate the values)
- var message = $"{requestId}{userName}";
+ var message = $"{requestId}{walletAddress}";
// Sign the message
var signature = SignMessage(message, _settings.PrivateKey);
@@ -128,12 +124,12 @@ public class KaigenService : IKaigenService
var requestPayload = new
{
requestId = requestId,
- userName = userName,
+ walletAddress = walletAddress,
signature = signature
};
- _logger.LogInformation("Refunding credits for user {UserName} with request ID {RequestId}",
- userName, requestId);
+ _logger.LogInformation("Refunding credits for user {UserName} (wallet: {WalletAddress}) with request ID {RequestId}",
+ user.Name, walletAddress, requestId);
var response = await _httpClient.PutAsJsonAsync(
$"{_settings.BaseUrl}{_settings.RefundEndpoint}",
@@ -148,16 +144,34 @@ public class KaigenService : IKaigenService
return false;
}
- _logger.LogInformation("Successfully refunded credits for user {UserName}", userName);
+ _logger.LogInformation("Successfully refunded credits for user {UserName} (wallet: {WalletAddress})", user.Name, walletAddress);
return true;
}
catch (Exception ex)
{
- _logger.LogError(ex, "Error refunding credits for user {UserName}", userName);
+ _logger.LogError(ex, "Error refunding credits for user {UserName}", user.Name);
return false;
}
}
+ private string GetUserWalletAddress(User user)
+ {
+ if (user?.Accounts == null || !user.Accounts.Any())
+ {
+ throw new InvalidOperationException($"No accounts found for user {user?.Name}");
+ }
+
+ // Use the first account's key as the wallet address
+ var walletAddress = user.Accounts[0].Key;
+
+ if (string.IsNullOrEmpty(walletAddress))
+ {
+ throw new InvalidOperationException($"No wallet address found for user {user.Name}");
+ }
+
+ return walletAddress;
+ }
+
private string SignMessage(string message, string privateKey)
{
var signer = new EthereumMessageSigner();