private async Task <OffchainResult> ProcessTransfer(IWalletCredentials credentials, IOffchainTransfer offchainTransfer, string revokePubKey, string encryptedRevokePrivakeKey,
                                                            string signedCommitment)
        {
            var result = await _bitcoinApiClient.Finalize(new FinalizeData
            {
                ClientPubKey                = credentials.PublicKey,
                AssetId                     = offchainTransfer.AssetId,
                ClientRevokePubKey          = revokePubKey,
                SignedByClientHubCommitment = signedCommitment,
                ExternalTransferId          = offchainTransfer.ExternalTransferId,
                OffchainTransferId          = offchainTransfer.Id
            });

            await _offchainEncryptedKeysRepository.UpdateKey(credentials.ClientId, offchainTransfer.AssetId, encryptedRevokePrivakeKey);

            if (result.HasError)
            {
                return(await InternalErrorProcessing(nameof(ProcessTransfer), result.Error, credentials, offchainTransfer, required : false));
            }

            await _offchainTransferRepository.CompleteTransfer(offchainTransfer.Id, blockchainHash : result.TxHash);

            await _offchainFinalizeCommandProducer.ProduceFinalize(offchainTransfer.Id, credentials.ClientId, result.TxHash);

            return(new OffchainResult
            {
                TransferId = offchainTransfer.Id,
                TransactionHex = "0x0", //result.Transaction,
                OperationResult = OffchainOperationResult.ClientCommitment
            });
        }
        private async Task FinalizeSwap(IBitcoinTransaction transaction, IOffchainTransfer offchainTransfer)
        {
            var transactionsContextData = new Dictionary <string, SwapOffchainContextData>();

            var allTransfers = new HashSet <string>(offchainTransfer.GetAdditionalData().ChildTransfers)
            {
                offchainTransfer.Id
            };

            foreach (var transferId in allTransfers)
            {
                try
                {
                    var transfer = await _offchainTransferRepository.GetTransfer(transferId);

                    if (!transactionsContextData.ContainsKey(transfer.OrderId))
                    {
                        var ctx = await _bitcoinTransactionService.GetTransactionContext <SwapOffchainContextData>(transaction.TransactionId);

                        if (ctx == null)
                        {
                            continue;
                        }

                        transactionsContextData.Add(transfer.OrderId, ctx);
                    }

                    var contextData = transactionsContextData[transfer.OrderId];

                    var operation = contextData.Operations.FirstOrDefault(x => x.TransactionId == transferId);

                    if (operation == null)
                    {
                        continue;
                    }

                    if (string.IsNullOrWhiteSpace(operation?.ClientTradeId) || string.IsNullOrWhiteSpace(operation?.ClientId))
                    {
                        await _log.WriteWarningAsync(nameof(OffchainTransactionFinalizeFunction),
                                                     nameof(FinalizeSwap), operation?.ToJson(),
                                                     $"Missing fields. Client trade id {operation?.ClientTradeId}, client {operation?.ClientId}, transfer: {transferId}");

                        continue;
                    }

                    await Task.WhenAll(
                        _offchainTransferRepository.CompleteTransfer(transferId),
                        _clientTradesRepository.SetIsSettledAsync(operation.ClientId, operation.ClientTradeId, true)
                        );
                }
                catch (Exception e)
                {
                    await _log.WriteErrorAsync(nameof(OffchainTransactionFinalizeFunction), nameof(FinalizeSwap), $"Transfer: {transferId}", e);
                }
            }
        }