public async Task <OffchainResult> CreateHubCommitment(string clientId, string transferId, string signedChannel) { var credentials = await _walletCredentialsRepository.GetAsync(clientId); var offchainTransfer = await _offchainTransferRepository.GetTransfer(transferId); if (offchainTransfer.Completed) { await _logger.WriteErrorAsync("CreateHubCommitment", (new { ClientId = clientId, TransferId = transferId }).ToJson() + " Offchain transfer already completed!", new OffchainException(ErrorCode.Exception, offchainTransfer.AssetId)); throw new OffchainException(ErrorCode.Exception, offchainTransfer.AssetId); } if (offchainTransfer.ClientId != clientId) { await _logger.WriteErrorAsync("CreateHubCommitment", (new { ClientId = clientId, TransferId = transferId }).ToJson() + $" Offchain transfer set for a different client: offchainTransfer.ClientId=={offchainTransfer.ClientId}!", new OffchainException(ErrorCode.Exception, offchainTransfer.AssetId)); throw new OffchainException(ErrorCode.Exception, offchainTransfer.AssetId); } var amount = 0.0M; switch (offchainTransfer.Type) { case OffchainTransferType.DirectTransferFromClient: amount = -offchainTransfer.Amount; break; default: throw new OffchainException(ErrorCode.OperationNotSupported, $"Unsuported offchainTransfer.Type: {offchainTransfer.Type} while initializing CreateHubCommitment.", "", "", false); } var result = await _bitcoinApiClient.CreateHubCommitment(new CreateHubComitmentData { Amount = amount, ClientPubKey = credentials.PublicKey, AssetId = offchainTransfer.AssetId, SignedByClientChannel = signedChannel }); if (result.HasError) { return(await InternalErrorProcessing("ProcessClientTransfer", result.Error, credentials, offchainTransfer, required : false)); } return(new OffchainResult { TransferId = offchainTransfer.Id, TransactionHex = result.Transaction, OperationResult = OffchainOperationResult.Transfer }); }
public async Task Process(OffchainFinalizetionMessage message) { var transfer = await _offchainTransferRepository.GetTransfer(message.TransferId); if (transfer.Type == OffchainTransferType.HubCashout || transfer.Type == OffchainTransferType.CashinFromClient) { return; } var transactionId = transfer.Type == OffchainTransferType.FromClient || transfer.Type == OffchainTransferType.FromHub ? transfer.OrderId : transfer.Id; var transaction = await _bitCoinTransactionsRepository.SaveResponseAndHashAsync(transactionId, null, message.TransactionHash); if (transaction == null) { await _log.WriteWarningAsync(nameof(OffchainTransactionFinalizeFunction), nameof(Process), $"Transaction: {transactionId}, client: {message.ClientId}, hash: {message.TransactionHash}, transfer: {message.TransferId}", "unkown transaction"); return; } switch (transaction.CommandType) { case BitCoinCommands.Issue: await FinalizeIssue(transaction); break; case BitCoinCommands.CashOut: await FinalizeCashOut(transaction, transfer); break; case BitCoinCommands.Transfer: await FinalizeTransfer(transaction, transfer); break; case BitCoinCommands.SwapOffchain: await FinalizeSwap(transaction, transfer); break; default: await _log.WriteWarningAsync(nameof(OffchainTransactionFinalizeFunction), nameof(Process), $"Transaction: {transactionId}, client: {message.ClientId}, hash: {message.TransactionHash}, transfer: {message.TransferId}", "unkown command type"); break; } }
private async Task AggregateRequests(string clientId, string asset, OffchainTransferType type) { var list = (await _offchainRequestRepository.GetRequestsForClient(clientId)).Where(x => x.AssetId == asset && x.TransferType == type).ToList(); var masterRequest = list.FirstOrDefault(x => (x.StartProcessing == null || (DateTime.UtcNow - x.StartProcessing.Value).TotalMinutes > 5) && x.ServerLock == null); if (masterRequest == null) { return; } await _offchainRequestRepository.DeleteRequest(masterRequest.RequestId); LogToFile(masterRequest.ToJson()); var masterTransfer = await _offchainTransferRepository.GetTransfer(masterRequest.TransferId); int count = 0; while (count < 50) { list = (await _offchainRequestRepository.GetRequestsForClient(clientId)) .Where(x => (x.StartProcessing == null || (DateTime.UtcNow - x.StartProcessing.Value).TotalMinutes > 5) && x.ServerLock == null) .Where(x => x.AssetId == asset && x.RequestId != masterRequest.RequestId && x.TransferType == type).ToList(); if (list.Count < 1) { break; } var current = list.FirstOrDefault(); await _offchainRequestRepository.DeleteRequest(current.RequestId); LogToFile(current.ToJson()); var currentTransfer = await _offchainTransferRepository.GetTransfer(current.TransferId); await _offchainTransferRepository.SetTransferIsChild(currentTransfer.Id, masterTransfer.Id); await _offchainTransferRepository.AddChildTransfer(masterTransfer.Id, currentTransfer); count++; } await _offchainRequestRepository.CreateRequest(masterTransfer.Id, masterTransfer.ClientId, masterTransfer.AssetId, masterRequest.Type, masterTransfer.Type); }
private async void AttachSenderTransferToRefLink(IReferralLink refLink, string transferId) { var transfer = await _offchainTransferRepository.GetTransfer(transferId); refLink.Amount = (double)transfer.Amount; refLink.Asset = (await _assets.GetItemAsync(transfer.AssetId)).Id; refLink.SenderOffchainTransferId = transferId; refLink.State = ReferralLinkState.SentToLykkeSharedWallet.ToString(); await _referralLinksService.UpdateAsync(refLink); await LogInfo(new { RefLink = refLink, TransferId = transferId }, ControllerContext, $"Transfer complete for ref link id {refLink.Id} with amount {transfer.Amount} and asset Id {refLink.Asset}. Offchain transfer Id {transferId} attached with ref link. "); }