private async Task HandleWalletUnlinkedAsync(string[] topics, string data) { var publicAccountUnlinkedDto = _blockchainEventDecoder.DecodePublicAccountUnlinkedEvent(topics, data); var linkRequest = await _requestsRepository.GetByPrivateAddressAsync(publicAccountUnlinkedDto.PrivateAddress); if (linkRequest != null) { await _pushNotificationsPublisher.PublishWalletUnlinkingSuccessfulAsync(linkRequest.CustomerId); await _requestsRepository.DeleteByIdAsync(linkRequest.CustomerId); } else { _log.Error(message: "Wallet linking request has not been deleted upon confirmation from blockchain", context: new { publicAccountUnlinkedDto.PrivateAddress, publicAccountUnlinkedDto.PublicAddress }); } await _statusChangeCompletedPublisher.PublishAsync(new WalletLinkingStatusChangeCompletedEvent { CustomerId = linkRequest?.CustomerId, PrivateAddress = publicAccountUnlinkedDto.PrivateAddress, PublicAddress = null, EventId = Guid.NewGuid().ToString(), Fee = linkRequest?.Fee ?? 0 }); _log.Info("Wallet has been unlinked and confirmed in private blockchain", context: publicAccountUnlinkedDto.ToJson()); }
public async Task HandleAsync(string privateAddress, string publicAddress) { var linkingRequest = await _requestsRepository.GetByPrivateAddressAsync(privateAddress); if (string.IsNullOrEmpty(publicAddress)) { // it was unlink operation _log.Error(message: "Wallet unlinking operation failed", context: new { privateAddress }); if (linkingRequest != null) { await _pushNotificationsPublisher.PublishWalletUnlinkingUnsuccessfulAsync(linkingRequest.CustomerId); } } else { // it was link operation _log.Error(message: "Wallet linking operation failed", context: new { privateAddress, publicAddress }); if (linkingRequest != null) { await _requestsRepository.DeleteByIdAsync(linkingRequest.CustomerId); await _pushNotificationsPublisher.PublishWalletLinkingUnsuccessfulAsync(linkingRequest.CustomerId); _log.Info("The linking request has been deleted because the corresponding transaction failed", context: linkingRequest.ToJson()); } } await _failurePublisher.PublishAsync(new WalletLinkingStatusChangeFailedEvent { CustomerId = linkingRequest?.CustomerId, PrivateAddress = privateAddress, PublicAddress = publicAddress, Fee = linkingRequest?.Fee ?? 0, EventId = Guid.NewGuid().ToString() }); }
public async Task <LinkingApprovalResultModel> ApproveLinkRequestAsync(string privateAddress, string publicAddress, string signature) { #region Validation if (string.IsNullOrEmpty(privateAddress)) { return(LinkingApprovalResultModel.Failed(LinkingError.InvalidPrivateAddress)); } if (string.IsNullOrEmpty(publicAddress)) { return(LinkingApprovalResultModel.Failed(LinkingError.InvalidPublicAddress)); } if (string.IsNullOrEmpty(signature)) { return(LinkingApprovalResultModel.Failed(LinkingError.InvalidSignature)); } var linkRequest = await _requestsRepository.GetByPrivateAddressAsync(privateAddress); if (linkRequest == null) { return(LinkingApprovalResultModel.Failed(LinkingError.LinkingRequestDoesNotExist)); } if (linkRequest.IsApproved()) { return(LinkingApprovalResultModel.Failed(LinkingError.LinkingRequestAlreadyApproved)); } var walletError = await CheckWalletStatus(linkRequest.CustomerId); if (walletError != LinkingError.None) { return(LinkingApprovalResultModel.Failed(walletError)); } if (!_signatureValidator.Validate(linkRequest.LinkCode, signature, publicAddress)) { return(LinkingApprovalResultModel.Failed(LinkingError.InvalidSignature)); } var fee = await _customersService.GetNextWalletLinkingFeeAsync(Guid.Parse(linkRequest.CustomerId)); if (fee > 0) { var balanceResult = await _pbfClient.CustomersApi.GetBalanceAsync(Guid.Parse(linkRequest.CustomerId)); if (balanceResult.Error != CustomerBalanceError.None) { _log.Error(message: "Couldn't get balance for customer wallet", context: new { customerId = linkRequest.CustomerId, error = balanceResult.Error.ToString() }); return(LinkingApprovalResultModel.Failed(LinkingError.NotEnoughFunds)); } if (balanceResult.Total < fee) { _log.Warning("The balance is not enough to pay wallet linking fee", context: new { balanceTotal = balanceResult.Total, fee }); return(LinkingApprovalResultModel.Failed(LinkingError.NotEnoughFunds)); } } #endregion await _transactionRunner.RunWithTransactionAsync(async txContext => { await _requestsRepository.SetApprovedAsync(linkRequest.CustomerId, publicAddress, signature, fee, txContext); var counter = await _countersRepository.GetAsync(linkRequest.CustomerId, txContext); var newCounterValue = counter?.ApprovalsCounter + 1 ?? 1; await _countersRepository.UpsertAsync(linkRequest.CustomerId, newCounterValue, txContext); }); await PublishLinkCommandAsync(linkRequest.CustomerId, privateAddress, publicAddress, fee); _log.Info("Wallet linking request has been approved", new { linkRequest.CustomerId, publicAddress, fee }); return(LinkingApprovalResultModel.Succeeded()); }