From a83da45d245b012e79b24d738cb66f8056283b0d Mon Sep 17 00:00:00 2001 From: Stan Goldin <48094744+Lomet@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:43:18 +0300 Subject: [PATCH] refactor: introduce unified phase context --- .../Services/DefaultServiceProvider.cs | 2 + .../Models/AdminCreatePoolzBackIdRequest.cs | 22 +++++-- .../AdminWriteAllocationHandler.cs | 3 +- .../Models/AdminWriteAllocationRequest.cs | 15 ++--- .../Services/Handlers/BasePhaseValidator.cs | 30 ++++----- .../ContextBuilders/PhaseContextBuilder.cs | 35 ++++++---- .../Handlers/Contexts/ContextModels.cs | 66 ------------------- .../Handlers/Contexts/PhaseContext.cs | 39 +++++++++++ .../GenerateSignatureHandler.cs | 18 ++--- .../GenerateSignatureValidator.Helpers.cs | 28 ++++---- .../GenerateSignatureValidator.cs | 22 +++---- .../Models/GenerateSignatureRequest.cs | 30 ++------- .../Models/MyAllocationRequest.cs | 22 ++----- .../MyAllocation/MyAllocationHandler.cs | 9 +-- .../MyAllocation/MyAllocationValidator.cs | 4 +- 15 files changed, 153 insertions(+), 192 deletions(-) delete mode 100644 src/InvestProvider.Backend/Services/Handlers/Contexts/ContextModels.cs create mode 100644 src/InvestProvider.Backend/Services/Handlers/Contexts/PhaseContext.cs diff --git a/src/InvestProvider.Backend/Services/DefaultServiceProvider.cs b/src/InvestProvider.Backend/Services/DefaultServiceProvider.cs index ec63313..f3c3fc1 100644 --- a/src/InvestProvider.Backend/Services/DefaultServiceProvider.cs +++ b/src/InvestProvider.Backend/Services/DefaultServiceProvider.cs @@ -6,6 +6,7 @@ using InvestProvider.Backend.Services.Strapi; using Microsoft.Extensions.DependencyInjection; using poolz.finance.csharp.contracts.LockDealNFT; +using InvestProvider.Backend.Services.Handlers.Contexts; using InvestProvider.Backend.Services.Web3.Eip712; using poolz.finance.csharp.contracts.InvestProvider; using InvestProvider.Backend.Services.Web3.Contracts; @@ -29,6 +30,7 @@ public static class DefaultServiceProvider .AddFluentValidation([Assembly.GetExecutingAssembly()]) .AddTransient(typeof(IPipelineBehavior<,>), typeof(ContextBuilderBehavior<,>)) .AddTransient(typeof(IRequestContextBuilder<>), typeof(PhaseContextBuilder<>)) + .AddScoped() .AddSingleton() .AddSingleton, ChainProvider>() .AddSingleton() diff --git a/src/InvestProvider.Backend/Services/Handlers/AdminCreatePoolzBackId/Models/AdminCreatePoolzBackIdRequest.cs b/src/InvestProvider.Backend/Services/Handlers/AdminCreatePoolzBackId/Models/AdminCreatePoolzBackIdRequest.cs index ecaa2cf..3eed32d 100644 --- a/src/InvestProvider.Backend/Services/Handlers/AdminCreatePoolzBackId/Models/AdminCreatePoolzBackIdRequest.cs +++ b/src/InvestProvider.Backend/Services/Handlers/AdminCreatePoolzBackId/Models/AdminCreatePoolzBackIdRequest.cs @@ -1,21 +1,21 @@ using MediatR; using Newtonsoft.Json; using Amazon.DynamoDBv2.DataModel; -using InvestProvider.Backend.Services.Strapi.Models; -using InvestProvider.Backend.Services.DynamoDb.Models; using InvestProvider.Backend.Services.Handlers.Contexts; +using Net.Web3.EthereumWallet; +using ProjectsInformation = InvestProvider.Backend.Services.DynamoDb.Models.ProjectsInformation; namespace InvestProvider.Backend.Services.Handlers.AdminCreatePoolzBackId.Models; public class AdminCreatePoolzBackIdRequest : ProjectsInformation, IRequest, - IExistActivePhase, - IInvestPool + IPhaseRequest { [JsonRequired] [DynamoDBIgnore] public long ChainId { get; set; } + string IPhaseRequest.ProjectId => ProjectId; [JsonIgnore] [DynamoDBIgnore] @@ -23,9 +23,19 @@ public class AdminCreatePoolzBackIdRequest : [JsonIgnore] [DynamoDBIgnore] - public ProjectInfo StrapiProjectInfo { get; set; } = null!; + public EthereumAddress? UserAddress => null; [JsonIgnore] [DynamoDBIgnore] - public string PhaseId => StrapiProjectInfo.CurrentPhase!.Id; + public string? WeiAmount => null; + + [JsonIgnore] + [DynamoDBIgnore] + public string? PhaseId => Context.StrapiProjectInfo?.CurrentPhase?.Id; + + [JsonIgnore] + [DynamoDBIgnore] + public PhaseContext Context { get; set; } = null!; + + long? IPhaseRequest.ChainId => ChainId; } \ No newline at end of file diff --git a/src/InvestProvider.Backend/Services/Handlers/AdminWriteAllocation/AdminWriteAllocationHandler.cs b/src/InvestProvider.Backend/Services/Handlers/AdminWriteAllocation/AdminWriteAllocationHandler.cs index 5fc9fcd..b3524e1 100644 --- a/src/InvestProvider.Backend/Services/Handlers/AdminWriteAllocation/AdminWriteAllocationHandler.cs +++ b/src/InvestProvider.Backend/Services/Handlers/AdminWriteAllocation/AdminWriteAllocationHandler.cs @@ -15,7 +15,8 @@ public class AdminWriteAllocationHandler(IDynamoDBContext dynamoDb) public async Task Handle(AdminWriteAllocationRequest request, CancellationToken cancellationToken) { - var toSave = request.Users.Select(x => new WhiteList(request.ProjectId, request.Phase.Start!.Value, x.UserAddress.ConvertToChecksumAddress(), x.Amount)).ToArray(); + var ctx = request.Context; + var toSave = request.Users.Select(x => new WhiteList(request.ProjectId, ctx.Phase!.Start!.Value, x.UserAddress.ConvertToChecksumAddress(), x.Amount)).ToArray(); await Parallel.ForEachAsync(toSave.Chunk(BatchSize), new ParallelOptions { MaxDegreeOfParallelism = MaxParallel, diff --git a/src/InvestProvider.Backend/Services/Handlers/AdminWriteAllocation/Models/AdminWriteAllocationRequest.cs b/src/InvestProvider.Backend/Services/Handlers/AdminWriteAllocation/Models/AdminWriteAllocationRequest.cs index c632cb8..5aadb60 100644 --- a/src/InvestProvider.Backend/Services/Handlers/AdminWriteAllocation/Models/AdminWriteAllocationRequest.cs +++ b/src/InvestProvider.Backend/Services/Handlers/AdminWriteAllocation/Models/AdminWriteAllocationRequest.cs @@ -1,17 +1,14 @@ using MediatR; using Newtonsoft.Json; using Poolz.Finance.CSharp.Strapi; -using InvestProvider.Backend.Services.Strapi.Models; using InvestProvider.Backend.Services.Handlers.Contexts; -using ProjectsInformation = InvestProvider.Backend.Services.DynamoDb.Models.ProjectsInformation; +using Net.Web3.EthereumWallet; namespace InvestProvider.Backend.Services.Handlers.AdminWriteAllocation.Models; public class AdminWriteAllocationRequest(string projectId, string phaseId, ICollection users) : IRequest, - IValidatedDynamoDbProjectInfo, - IExistPhase, - IWhiteListPhase + IPhaseRequest { [JsonRequired] public string ProjectId { get; } = projectId; @@ -26,14 +23,14 @@ public class AdminWriteAllocationRequest(string projectId, string phaseId, IColl public bool FilterPhases => false; [JsonIgnore] - public ProjectInfo StrapiProjectInfo { get; set; } = null!; + public long? ChainId => Context.StrapiProjectInfo?.ChainId; [JsonIgnore] - public long ChainId => StrapiProjectInfo.ChainId; + public EthereumAddress? UserAddress => null; [JsonIgnore] - public ProjectsInformation DynamoDbProjectsInfo { get; set; } = null!; + public string? WeiAmount => null; [JsonIgnore] - public ComponentPhaseStartEndAmount Phase { get; set; } = null!; + public PhaseContext Context { get; set; } = null!; } \ No newline at end of file diff --git a/src/InvestProvider.Backend/Services/Handlers/BasePhaseValidator.cs b/src/InvestProvider.Backend/Services/Handlers/BasePhaseValidator.cs index 3752ad2..02fa5c7 100644 --- a/src/InvestProvider.Backend/Services/Handlers/BasePhaseValidator.cs +++ b/src/InvestProvider.Backend/Services/Handlers/BasePhaseValidator.cs @@ -6,26 +6,26 @@ namespace InvestProvider.Backend.Services.Handlers; public abstract class BasePhaseValidator : AbstractValidator - where T : IExistActivePhase + where T : IPhaseRequest { - protected static bool HasCurrentPhase(IExistActivePhase model) => - model.StrapiProjectInfo.CurrentPhase != null; + protected static bool HasCurrentPhase(IPhaseRequest model) => + model.Context.StrapiProjectInfo?.CurrentPhase != null; - protected static bool HasProjectsInformation(IValidatedDynamoDbProjectInfo model) => - model.DynamoDbProjectsInfo != null; + protected static bool HasProjectsInformation(IPhaseRequest model) => + model.Context.DynamoDbProjectsInfo != null; - protected static bool SetPhase(IExistPhase model) + protected static bool SetPhase(IPhaseRequest model) { - var phase = model.StrapiProjectInfo.Phases.FirstOrDefault(p => p.Id == model.PhaseId); - model.Phase = phase!; + var phase = model.Context.StrapiProjectInfo?.Phases.FirstOrDefault(p => p.Id == model.Context.PhaseId); + model.Context.Phase = phase!; return phase != null; } - protected static bool HasWhiteList(IWhiteListUser model) => - model.WhiteList != null; + protected static bool HasWhiteList(IPhaseRequest model) => + model.Context.WhiteList != null; protected static IRuleBuilderOptions WhiteListPhaseRules(BasePhaseValidator validator) - where TModel : IExistPhase, IValidatedDynamoDbProjectInfo + where TModel : IPhaseRequest { return validator.RuleFor(x => x) .Cascade(CascadeMode.Stop) @@ -35,10 +35,10 @@ protected static IRuleBuilderOptions WhiteListPhaseRules .WithError(Error.NOT_FOUND_ACTIVE_PHASE, x => new { x.ProjectId }) .Must(m => SetPhase(m)) .WithError(Error.PHASE_IN_PROJECT_NOT_FOUND, x => new { x.ProjectId, x.PhaseId }) - .Must(x => DateTime.UtcNow < x.Phase.Finish) - .WithError(Error.PHASE_FINISHED, x => new { EndTime = x.Phase.Finish, NowTime = DateTime.UtcNow }) - .Must(x => x.Phase.MaxInvest == 0) + .Must(x => DateTime.UtcNow < x.Context.Phase!.Finish) + .WithError(Error.PHASE_FINISHED, x => new { EndTime = x.Context.Phase!.Finish, NowTime = DateTime.UtcNow }) + .Must(x => x.Context.Phase!.MaxInvest == 0) .WithError(Error.PHASE_IS_NOT_WHITELIST) - .When(x => x.StrapiProjectInfo.CurrentPhase!.MaxInvest == 0, ApplyConditionTo.CurrentValidator); + .When(x => x.Context.StrapiProjectInfo!.CurrentPhase!.MaxInvest == 0, ApplyConditionTo.CurrentValidator); } } diff --git a/src/InvestProvider.Backend/Services/Handlers/ContextBuilders/PhaseContextBuilder.cs b/src/InvestProvider.Backend/Services/Handlers/ContextBuilders/PhaseContextBuilder.cs index 513d4ec..b672b7a 100644 --- a/src/InvestProvider.Backend/Services/Handlers/ContextBuilders/PhaseContextBuilder.cs +++ b/src/InvestProvider.Backend/Services/Handlers/ContextBuilders/PhaseContextBuilder.cs @@ -2,31 +2,42 @@ using InvestProvider.Backend.Services.DynamoDb.Models; using InvestProvider.Backend.Services.Strapi; using InvestProvider.Backend.Services.Handlers.Contexts; +using InvestProvider.Backend.Services.Handlers.AdminGetAllocation.Models; +using InvestProvider.Backend.Services.Handlers.MyUpcomingAllocation.Models; namespace InvestProvider.Backend.Services.Handlers.ContextBuilders; -public class PhaseContextBuilder(IStrapiClient strapi, IDynamoDBContext dynamoDb) +public class PhaseContextBuilder(IStrapiClient strapi, IDynamoDBContext dynamoDb, PhaseContext context) : IRequestContextBuilder - where T : IExistActivePhase { public async Task BuildAsync(T request, CancellationToken cancellationToken) { - request.StrapiProjectInfo = await strapi.ReceiveProjectInfoAsync( - request.ProjectId, - request.FilterPhases); + if (request is not IPhaseRequest phaseRequest) + return; - if (request is IValidatedDynamoDbProjectInfo validated) + phaseRequest.Context = context; + context.ProjectId = phaseRequest.ProjectId; + context.FilterPhases = phaseRequest.FilterPhases; + context.PhaseId = phaseRequest.PhaseId; + context.UserAddress = phaseRequest.UserAddress; + context.WeiAmount = phaseRequest.WeiAmount; + + context.StrapiProjectInfo = await strapi.ReceiveProjectInfoAsync( + context.ProjectId, + context.FilterPhases); + + if (phaseRequest is not AdminGetAllocationRequest && phaseRequest is not MyUpcomingAllocationRequest) { - validated.DynamoDbProjectsInfo = await dynamoDb.LoadAsync( - request.ProjectId, + context.DynamoDbProjectsInfo = await dynamoDb.LoadAsync( + context.ProjectId, cancellationToken); } - if (request is IWhiteListUser whiteListUser && request.StrapiProjectInfo.CurrentPhase != null) + if (context.UserAddress != null && context.StrapiProjectInfo.CurrentPhase != null) { - whiteListUser.WhiteList = await dynamoDb.LoadAsync( - WhiteList.CalculateHashId(request.ProjectId, request.StrapiProjectInfo.CurrentPhase.Start!.Value), - whiteListUser.UserAddress.Address, + context.WhiteList = await dynamoDb.LoadAsync( + WhiteList.CalculateHashId(context.ProjectId, context.StrapiProjectInfo.CurrentPhase.Start!.Value), + context.UserAddress.Address, cancellationToken); } } diff --git a/src/InvestProvider.Backend/Services/Handlers/Contexts/ContextModels.cs b/src/InvestProvider.Backend/Services/Handlers/Contexts/ContextModels.cs deleted file mode 100644 index b0ed2b1..0000000 --- a/src/InvestProvider.Backend/Services/Handlers/Contexts/ContextModels.cs +++ /dev/null @@ -1,66 +0,0 @@ -using Poolz.Finance.CSharp.Strapi; -using InvestProvider.Backend.Services.Strapi.Models; -using ProjectsInformation = InvestProvider.Backend.Services.DynamoDb.Models.ProjectsInformation; -using InvestProvider.Backend.Services.DynamoDb.Models; -using InvestProvider.Backend.Services.Web3.Contracts.Models; -using Net.Web3.EthereumWallet; - -namespace InvestProvider.Backend.Services.Handlers.Contexts; - -public interface IProjectContext -{ - string ProjectId { get; } - string PhaseId { get; } - long ChainId { get; } -} - -public interface IExistActivePhase : IProjectContext -{ - bool FilterPhases { get; } - ProjectInfo StrapiProjectInfo { get; set; } -} - -public interface IExistPhase : IExistActivePhase -{ - ComponentPhaseStartEndAmount Phase { get; set; } -} - -public interface IValidatedDynamoDbProjectInfo : IProjectContext -{ - ProjectsInformation DynamoDbProjectsInfo { get; set; } -} - -public interface IValidatedInvestAmount : IExistActivePhase, IValidatedDynamoDbProjectInfo -{ - decimal Amount { get; set; } - byte TokenDecimals { get; set; } - string WeiAmount { get; } -} - -public interface IHasUserInvestments : IValidatedInvestAmount -{ - UserInvestments[] UserInvestments { get; set; } - decimal InvestedAmount { get; set; } - EthereumAddress UserAddress { get; } -} - -public interface IInvestPool : IProjectContext -{ - long PoolzBackId { get; } -} - -public interface IWhiteListPhase -{ - ComponentPhaseStartEndAmount Phase { get; } -} - -public interface IWhiteListUser : IExistActivePhase -{ - WhiteList WhiteList { get; set; } - EthereumAddress UserAddress { get; } -} - -public interface IWhiteListSignature : IHasUserInvestments -{ - WhiteList WhiteList { get; set; } -} diff --git a/src/InvestProvider.Backend/Services/Handlers/Contexts/PhaseContext.cs b/src/InvestProvider.Backend/Services/Handlers/Contexts/PhaseContext.cs new file mode 100644 index 0000000..e0675bd --- /dev/null +++ b/src/InvestProvider.Backend/Services/Handlers/Contexts/PhaseContext.cs @@ -0,0 +1,39 @@ +using Poolz.Finance.CSharp.Strapi; +using InvestProvider.Backend.Services.Strapi.Models; +using ProjectsInformation = InvestProvider.Backend.Services.DynamoDb.Models.ProjectsInformation; +using InvestProvider.Backend.Services.DynamoDb.Models; +using InvestProvider.Backend.Services.Web3.Contracts.Models; +using Net.Web3.EthereumWallet; + +namespace InvestProvider.Backend.Services.Handlers.Contexts; + +public class PhaseContext +{ + public required string ProjectId { get; set; } + public bool FilterPhases { get; set; } = true; + + public string? PhaseId { get; set; } + public EthereumAddress? UserAddress { get; set; } + public string? WeiAmount { get; set; } + + public ProjectInfo? StrapiProjectInfo { get; set; } + public ProjectsInformation? DynamoDbProjectsInfo { get; set; } + public ComponentPhaseStartEndAmount? Phase { get; set; } + public WhiteList? WhiteList { get; set; } + public UserInvestments[]? UserInvestments { get; set; } + public byte TokenDecimals { get; set; } + public decimal Amount { get; set; } + public decimal InvestedAmount { get; set; } + public long ChainId => StrapiProjectInfo?.ChainId ?? 0; +} + +public interface IPhaseRequest +{ + string ProjectId { get; } + bool FilterPhases { get; } + string? PhaseId { get; } + EthereumAddress? UserAddress { get; } + string? WeiAmount { get; } + long? ChainId { get; } + PhaseContext Context { get; set; } +} diff --git a/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureHandler.cs b/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureHandler.cs index 78533de..b44cd55 100644 --- a/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureHandler.cs +++ b/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureHandler.cs @@ -17,8 +17,8 @@ ISignatureGenerator signatureGenerator public Task Handle(GenerateSignatureRequest request, CancellationToken cancellationToken) => Task.FromResult(new GenerateSignatureResponse( GetSignature(chainProvider, signatureGenerator, request), - request.StrapiProjectInfo.CurrentPhase!.Finish!.Value, - request.DynamoDbProjectsInfo.PoolzBackId + request.Context.StrapiProjectInfo!.CurrentPhase!.Finish!.Value, + request.Context.DynamoDbProjectsInfo!.PoolzBackId )); private static string GetSignature( @@ -27,15 +27,15 @@ private static string GetSignature( GenerateSignatureRequest request) => signatureGenerator.GenerateSignature( new Eip712Domain( - chainId: request.StrapiProjectInfo.ChainId, - verifyingContract: chainProvider.ContractAddress(request.StrapiProjectInfo.ChainId, ContractType.InvestedProvider) + chainId: request.Context.StrapiProjectInfo!.ChainId, + verifyingContract: chainProvider.ContractAddress(request.Context.StrapiProjectInfo!.ChainId, ContractType.InvestedProvider) ), new InvestMessage( - poolId: request.DynamoDbProjectsInfo.PoolzBackId, - userAddress: request.UserAddress, - amount: UnitConversion.Convert.ToWei(request.Amount, request.TokenDecimals), - validUntil: request.StrapiProjectInfo.CurrentPhase!.Finish!.Value, - nonce: request.UserInvestments.Length + poolId: request.Context.DynamoDbProjectsInfo!.PoolzBackId, + userAddress: request.Context.UserAddress!, + amount: UnitConversion.Convert.ToWei(request.Context.Amount, request.Context.TokenDecimals), + validUntil: request.Context.StrapiProjectInfo!.CurrentPhase!.Finish!.Value, + nonce: request.Context.UserInvestments!.Length ) ); } diff --git a/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureValidator.Helpers.cs b/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureValidator.Helpers.cs index 67a7eb8..160dffc 100644 --- a/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureValidator.Helpers.cs +++ b/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureValidator.Helpers.cs @@ -16,38 +16,38 @@ public partial class GenerateSignatureRequestValidator private async Task MustMoreThanAllowedMinimumAsync(GenerateSignatureRequest model, CancellationToken _) { var tokenAddress = await _lockDealNFT.TokenOfQueryAsync( - model.StrapiProjectInfo.ChainId, + model.Context.StrapiProjectInfo!.ChainId, ContractType.LockDealNFT, - model.DynamoDbProjectsInfo.PoolzBackId + model.Context.DynamoDbProjectsInfo!.PoolzBackId ); - model.TokenDecimals = _erc20Cache.GetOrAdd(new GetCacheRequest( - model.StrapiProjectInfo.ChainId, + model.Context.TokenDecimals = _erc20Cache.GetOrAdd(new GetCacheRequest( + model.Context.StrapiProjectInfo!.ChainId, tokenAddress, - _rpcProvider.RpcUrl(model.StrapiProjectInfo.ChainId) + _rpcProvider.RpcUrl(model.Context.StrapiProjectInfo!.ChainId) )).Decimals; - model.Amount = UnitConversion.Convert.FromWei(BigInteger.Parse(model.WeiAmount), model.TokenDecimals); + model.Context.Amount = UnitConversion.Convert.FromWei(BigInteger.Parse(model.WeiAmount), model.Context.TokenDecimals); - return model.Amount >= _minInvestAmount; + return model.Context.Amount >= _minInvestAmount; } private async Task SetUserInvestmentsAsync(GenerateSignatureRequest model, ValidationContext context, CancellationToken _) { var response = await _investProvider.GetUserInvestsQueryAsync( - model.StrapiProjectInfo.ChainId, + model.Context.StrapiProjectInfo!.ChainId, ContractType.InvestedProvider, - model.DynamoDbProjectsInfo.PoolzBackId, - model.UserAddress + model.Context.DynamoDbProjectsInfo!.PoolzBackId, + model.Context.UserAddress! ); - model.UserInvestments = response.ReturnValue1 + model.Context.UserInvestments = response.ReturnValue1 .Select(ui => new UserInvestments(ui)) .ToArray(); - model.InvestedAmount = model.UserInvestments - .Where(ui => ui.BlockCreation >= model.StrapiProjectInfo.CurrentPhase!.Start && ui.BlockCreation < model.StrapiProjectInfo.CurrentPhase.Finish) - .Sum(ui => UnitConversion.Convert.FromWei(ui.Amount, model.TokenDecimals)); + model.Context.InvestedAmount = model.Context.UserInvestments + .Where(ui => ui.BlockCreation >= model.Context.StrapiProjectInfo!.CurrentPhase!.Start && ui.BlockCreation < model.Context.StrapiProjectInfo.CurrentPhase.Finish) + .Sum(ui => UnitConversion.Convert.FromWei(ui.Amount, model.Context.TokenDecimals)); } } diff --git a/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureValidator.cs b/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureValidator.cs index fd7df08..7cac020 100644 --- a/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureValidator.cs +++ b/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/GenerateSignatureValidator.cs @@ -42,30 +42,30 @@ IInvestProviderService investProvider .MustAsync(MustMoreThanAllowedMinimumAsync) .WithError(Error.INVEST_AMOUNT_IS_LESS_THAN_ALLOWED, x => new { - UserAmount = x.Amount, + UserAmount = x.Context.Amount, MinInvestAmount = _minInvestAmount }) .CustomAsync(SetUserInvestmentsAsync); RuleFor(x => x) .Cascade(CascadeMode.Stop) - .Must(x => x.Amount <= x.StrapiProjectInfo.CurrentPhase!.MaxInvest) - .WithError(Error.AMOUNT_EXCEED_MAX_INVEST, x => new { x.StrapiProjectInfo.CurrentPhase!.MaxInvest }) - .Must(x => x.InvestedAmount == 0) + .Must(x => x.Context.Amount <= x.Context.StrapiProjectInfo!.CurrentPhase!.MaxInvest) + .WithError(Error.AMOUNT_EXCEED_MAX_INVEST, x => new { x.Context.StrapiProjectInfo!.CurrentPhase!.MaxInvest }) + .Must(x => x.Context.InvestedAmount == 0) .WithError(Error.ALREADY_INVESTED) - .When(x => x.StrapiProjectInfo.CurrentPhase!.MaxInvest != 0); + .When(x => x.Context.StrapiProjectInfo!.CurrentPhase!.MaxInvest != 0); RuleFor(x => x) .Cascade(CascadeMode.Stop) .Must(HasWhiteList) - .WithError(Error.NOT_IN_WHITE_LIST, x => new { x.ProjectId, PhaseId = x.StrapiProjectInfo.CurrentPhase!.Id, UserAddress = x.UserAddress.Address }) - .Must(x => x.Amount + x.InvestedAmount <= x.WhiteList.Amount) + .WithError(Error.NOT_IN_WHITE_LIST, x => new { x.ProjectId, PhaseId = x.Context.StrapiProjectInfo!.CurrentPhase!.Id, UserAddress = x.UserAddress.Address }) + .Must(x => x.Context.Amount + x.Context.InvestedAmount <= x.Context.WhiteList!.Amount) .WithError(Error.AMOUNT_EXCEED_MAX_WHITE_LIST_AMOUNT, x => new { - UserAmount = x.Amount, - MaxInvestAmount = x.WhiteList.Amount, - InvestSum = x.InvestedAmount + UserAmount = x.Context.Amount, + MaxInvestAmount = x.Context.WhiteList!.Amount, + InvestSum = x.Context.InvestedAmount }) - .When(x => x.StrapiProjectInfo.CurrentPhase!.MaxInvest == 0); + .When(x => x.Context.StrapiProjectInfo!.CurrentPhase!.MaxInvest == 0); } } diff --git a/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/Models/GenerateSignatureRequest.cs b/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/Models/GenerateSignatureRequest.cs index d447772..d1ddc0c 100644 --- a/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/Models/GenerateSignatureRequest.cs +++ b/src/InvestProvider.Backend/Services/Handlers/GenerateSignature/Models/GenerateSignatureRequest.cs @@ -1,18 +1,14 @@ using MediatR; using Newtonsoft.Json; using Net.Web3.EthereumWallet; -using InvestProvider.Backend.Services.Strapi.Models; -using InvestProvider.Backend.Services.DynamoDb.Models; using InvestProvider.Backend.Services.Handlers.Contexts; -using InvestProvider.Backend.Services.Web3.Contracts.Models; namespace InvestProvider.Backend.Services.Handlers.GenerateSignature.Models; [method: JsonConstructor] public class GenerateSignatureRequest(string projectId, EthereumAddress userAddress, string weiAmount) : IRequest, - IWhiteListSignature, - IWhiteListUser + IPhaseRequest { [JsonRequired] public string ProjectId { get; } = projectId; @@ -27,29 +23,11 @@ public class GenerateSignatureRequest(string projectId, EthereumAddress userAddr public bool FilterPhases => true; [JsonIgnore] - public decimal Amount { get; set; } + public string? PhaseId => Context.StrapiProjectInfo?.CurrentPhase?.Id; [JsonIgnore] - public byte TokenDecimals { get; set; } + public long? ChainId => Context.StrapiProjectInfo?.ChainId; [JsonIgnore] - public UserInvestments[] UserInvestments { get; set; } = null!; - - [JsonIgnore] - public decimal InvestedAmount { get; set; } - - [JsonIgnore] - public ProjectInfo StrapiProjectInfo { get; set; } = null!; - - [JsonIgnore] - public WhiteList WhiteList { get; set; } = null!; - - [JsonIgnore] - public ProjectsInformation DynamoDbProjectsInfo { get; set; } = null!; - - [JsonIgnore] - public string PhaseId => StrapiProjectInfo.CurrentPhase!.Id; - - [JsonIgnore] - public long ChainId => StrapiProjectInfo.ChainId; + public PhaseContext Context { get; set; } = null!; } \ No newline at end of file diff --git a/src/InvestProvider.Backend/Services/Handlers/MyAllocation/Models/MyAllocationRequest.cs b/src/InvestProvider.Backend/Services/Handlers/MyAllocation/Models/MyAllocationRequest.cs index 330ad93..78ee40f 100644 --- a/src/InvestProvider.Backend/Services/Handlers/MyAllocation/Models/MyAllocationRequest.cs +++ b/src/InvestProvider.Backend/Services/Handlers/MyAllocation/Models/MyAllocationRequest.cs @@ -2,20 +2,14 @@ using Newtonsoft.Json; using Net.Web3.EthereumWallet; using Poolz.Finance.CSharp.Strapi; -using InvestProvider.Backend.Services.Strapi.Models; -using InvestProvider.Backend.Services.DynamoDb.Models; using InvestProvider.Backend.Services.Handlers.Contexts; -using ProjectsInformation = InvestProvider.Backend.Services.DynamoDb.Models.ProjectsInformation; namespace InvestProvider.Backend.Services.Handlers.MyAllocation.Models; [method: JsonConstructor] public class MyAllocationRequest(string projectId, EthereumAddress userAddress) : IRequest, - IValidatedDynamoDbProjectInfo, - IExistPhase, - IWhiteListPhase, - IWhiteListUser + IPhaseRequest { [JsonRequired] public string ProjectId { get; } = projectId; @@ -27,20 +21,14 @@ public class MyAllocationRequest(string projectId, EthereumAddress userAddress) public bool FilterPhases => true; [JsonIgnore] - public string PhaseId => StrapiProjectInfo.CurrentPhase!.Id; + public string? PhaseId => Context.StrapiProjectInfo?.CurrentPhase?.Id; [JsonIgnore] - public ProjectInfo StrapiProjectInfo { get; set; } = null!; + public string? WeiAmount => null; [JsonIgnore] - public ComponentPhaseStartEndAmount Phase { get; set; } = null!; + public long? ChainId => Context.StrapiProjectInfo?.ChainId; [JsonIgnore] - public ProjectsInformation DynamoDbProjectsInfo { get; set; } = null!; - - [JsonIgnore] - public WhiteList? WhiteList { get; set; } - - [JsonIgnore] - public long ChainId => StrapiProjectInfo.ChainId; + public PhaseContext Context { get; set; } = null!; } \ No newline at end of file diff --git a/src/InvestProvider.Backend/Services/Handlers/MyAllocation/MyAllocationHandler.cs b/src/InvestProvider.Backend/Services/Handlers/MyAllocation/MyAllocationHandler.cs index 98b9dce..95c308e 100644 --- a/src/InvestProvider.Backend/Services/Handlers/MyAllocation/MyAllocationHandler.cs +++ b/src/InvestProvider.Backend/Services/Handlers/MyAllocation/MyAllocationHandler.cs @@ -7,11 +7,12 @@ public class MyAllocationHandler : IRequestHandler Handle(MyAllocationRequest request, CancellationToken cancellationToken) { + var ctx = request.Context; var response = new MyAllocationResponse( - amount: request.WhiteList?.Amount ?? (decimal)request.StrapiProjectInfo.CurrentPhase!.MaxInvest!, - startTime: request.StrapiProjectInfo.CurrentPhase!.Start!.Value, - endTime: request.StrapiProjectInfo.CurrentPhase.Finish!.Value, - poolzBackId: request.DynamoDbProjectsInfo.PoolzBackId + amount: ctx.WhiteList?.Amount ?? (decimal)ctx.StrapiProjectInfo!.CurrentPhase!.MaxInvest!, + startTime: ctx.StrapiProjectInfo!.CurrentPhase!.Start!.Value, + endTime: ctx.StrapiProjectInfo!.CurrentPhase!.Finish!.Value, + poolzBackId: ctx.DynamoDbProjectsInfo!.PoolzBackId ); return Task.FromResult(response); } diff --git a/src/InvestProvider.Backend/Services/Handlers/MyAllocation/MyAllocationValidator.cs b/src/InvestProvider.Backend/Services/Handlers/MyAllocation/MyAllocationValidator.cs index 736dc4b..8e5e1e8 100644 --- a/src/InvestProvider.Backend/Services/Handlers/MyAllocation/MyAllocationValidator.cs +++ b/src/InvestProvider.Backend/Services/Handlers/MyAllocation/MyAllocationValidator.cs @@ -12,7 +12,7 @@ public MyAllocationValidator() WhiteListPhaseRules(this) .Must(HasWhiteList) - .When(x => x.StrapiProjectInfo.CurrentPhase!.MaxInvest == 0, ApplyConditionTo.CurrentValidator) - .WithError(Error.NOT_IN_WHITE_LIST, x => new { x.ProjectId, PhaseId = x.StrapiProjectInfo.CurrentPhase!.Id, UserAddress = x.UserAddress.Address }); + .When(x => x.Context.StrapiProjectInfo!.CurrentPhase!.MaxInvest == 0, ApplyConditionTo.CurrentValidator) + .WithError(Error.NOT_IN_WHITE_LIST, x => new { x.ProjectId, PhaseId = x.Context.StrapiProjectInfo!.CurrentPhase!.Id, UserAddress = x.UserAddress.Address }); } }