public async Task Handle(CashoutTransactionStateSavedEvent evt) { var message = evt.Message; var walletCredentials = await _walletCredentialsRepository.GetAsync(message.ClientId); var amount = message.Amount.ParseAnyDouble(); var transactionId = evt.Command.TransactionId.ToString(); var context = await _transactionService.GetTransactionContext <CashOutContextData>(transactionId); var isForwardWithdawal = context.AddData?.ForwardWithdrawal != null; var operation = new CashInOutOperation { Id = context.CashOperationId, ClientId = message.ClientId, Multisig = walletCredentials?.MultiSig, AssetId = message.AssetId, Amount = -Math.Abs(amount), DateTime = DateTime.UtcNow, AddressFrom = walletCredentials?.MultiSig, AddressTo = context.Address, TransactionId = transactionId, Type = isForwardWithdawal ? CashOperationType.ForwardCashOut : CashOperationType.None, BlockChainHash = string.Empty, State = TransactionStates.SettledOffchain }; operation.AddFeeDataToOperation(message); await RegisterOperation(operation); }
public async Task Handle(ForwardWithdawalLinkedEvent evt) { var message = evt.Message; var walletCredentials = await _walletCredentialsRepository.GetAsync(message.ClientId); var amount = message.Amount.ParseAnyDouble(); var transactionId = message.Id; var context = await _transactionService.GetTransactionContext <CashOutContextData>(transactionId); var asset = await _assetsServiceWithCache.TryGetAssetAsync(message.AssetId); var baseAsset = await _assetsServiceWithCache.TryGetAssetAsync(asset.ForwardBaseAsset); var operation = new CashInOutOperation { Id = context.AddData.ForwardWithdrawal.Id, ClientId = message.ClientId, Multisig = walletCredentials?.MultiSig, AssetId = baseAsset.Id, Amount = Math.Abs(amount), DateTime = DateTime.UtcNow.AddDays(asset.ForwardFrozenDays), AddressFrom = walletCredentials?.MultiSig, AddressTo = context.Address, TransactionId = transactionId, Type = CashOperationType.ForwardCashIn, State = TransactionStates.InProcessOffchain }; operation.AddFeeDataToOperation(message); await RegisterOperation(operation); }
public async Task Handle(ManualTransactionStateSavedEvent evt) { var message = evt.Message; var walletCredentials = await _walletCredentialsRepository.GetAsync(message.ClientId); var transactionId = message.Id; var context = await _transactionService.GetTransactionContext <CashOutContextData>(transactionId); var operation = new CashInOutOperation { Id = transactionId, ClientId = message.ClientId, Multisig = walletCredentials?.MultiSig, AssetId = message.AssetId, Amount = message.Amount.ParseAnyDouble(), DateTime = DateTime.UtcNow, AddressFrom = walletCredentials?.MultiSig, AddressTo = context.Address, TransactionId = transactionId, Type = CashOperationType.None, BlockChainHash = string.Empty, State = TransactionStates.SettledOffchain }; operation.AddFeeDataToOperation(message); await RegisterOperation(operation); }
public async Task Handle(IssueTransactionStateSavedEvent evt) { var message = evt.Message; var multisig = evt.Command.Multisig; var amount = evt.Command.Amount; var transactionId = evt.Command.TransactionId.ToString(); var context = await _transactionService.GetTransactionContext <IssueContextData>(transactionId); var operation = new CashInOutOperation { Id = context.CashOperationId, ClientId = message.ClientId, Multisig = multisig, AssetId = message.AssetId, Amount = (double)Math.Abs(amount), DateTime = DateTime.UtcNow, AddressTo = multisig, TransactionId = transactionId, State = TransactionStates.SettledOffchain }; operation.AddFeeDataToOperation(message); await RegisterOperation(operation); }
public override Task <CashInOutOperationResponse> CashInOut(CashInOutOperation request, ServerCallContext context) { var isWithdrawal = double.Parse(request.Volume) < 0; using var activity = MyTelemetry.StartActivity(isWithdrawal ? "Withdrawal" : "Deposit"); activity?.AddTag("operationId", request.Id) .AddTag("brokerId", request.BrokerId) .AddTag("accountId", request.AccountId) .AddTag("walletId", request.WalletId) .AddTag("assetId", request.AssetId) .AddTag("volume", request.Volume); if (isWithdrawal && request.Fees.Count == 0) { var fees = _assetFeesClient.GetAssetFees(request.BrokerId, request.AssetId, OperationType.Withdrawal); if (fees != null) { request.Fees.Add(FeesConverter.ConvertAssetFee(fees)); } } return(_cashServiceClient.CashInOutAsync(request, cancellationToken: context.CancellationToken) .ResponseAsync); }
public async Task <OperationResponse> CashOutAsync(string brokerId, CashInOutModel model) { var wallet = await _accountsClient.Wallet.GetAsync((long)model.WalletId, brokerId); if (wallet == null) { throw new ArgumentException($"Wallet '{model.WalletId}' does not exist."); } var volume = model.Volume >= 0 ? -model.Volume : model.Volume; var request = new CashInOutOperation { Id = Guid.NewGuid().ToString(), BrokerId = brokerId, AccountId = model.AccountId, WalletId = model.WalletId, AssetId = model.Asset, Volume = volume.ToString(CultureInfo.InvariantCulture), Description = model.Description }; var fee = await GetFeeAsync(brokerId, model.Asset, RequestType.CashOut); request.Fees.Add(fee); var result = await _matchingEngineClient.CashOperations.CashInOutAsync(request); return(new OperationResponse(result)); }
private void AssertCashInOutOperation(CashInOutOperation cashInOutOperation, decimal volume) { Assert.NotNull(cashInOutOperation); Assert.NotEmpty(cashInOutOperation.Id); Assert.Equal(cashInOutOperation.BrokerId, BrokerId); Assert.Equal(cashInOutOperation.AccountId, AccountId); Assert.Equal(cashInOutOperation.WalletId, WalletId); Assert.Equal(cashInOutOperation.AssetId, Btc); Assert.Equal(cashInOutOperation.Volume, volume.ToString(CultureInfo.InvariantCulture)); Assert.Equal(cashInOutOperation.Description, Description); }
private async Task RegisterOperation(CashInOutOperation operation) { var operationId = await _cashOperationsRepositoryClient.RegisterAsync(operation); if (operationId != operation.Id) { _log.Warning($"Unexpected response from Operations Service: {operationId}", context: operation.ToJson()); } ChaosKitty.Meow(); }
private async Task <bool> ProcessManualOperation(IBitcoinTransaction transaction, CashInOutQueueMessage msg) { var asset = await _assetsService.TryGetAssetAsync(msg.AssetId); var walletCredentials = await _walletCredentialsRepository.GetAsync(msg.ClientId); var context = transaction.GetContextData <CashOutContextData>(); var isOffchainClient = await _clientSettingsRepository.IsOffchainClient(msg.ClientId); var isBtcOffchainClient = isOffchainClient && asset.Blockchain == Blockchain.Bitcoin; var operation = new CashInOutOperation { Id = Guid.NewGuid().ToString(), ClientId = msg.ClientId, Multisig = walletCredentials.MultiSig, AssetId = msg.AssetId, Amount = msg.Amount.ParseAnyDouble(), DateTime = DateTime.UtcNow, AddressFrom = walletCredentials.MultiSig, AddressTo = context.Address, TransactionId = msg.Id, Type = CashOperationType.None, BlockChainHash = asset.IssueAllowed && isBtcOffchainClient ? string.Empty : transaction.BlockchainHash, State = GetState(transaction, isBtcOffchainClient) }; var newHistoryEntry = new HistoryEntry { ClientId = operation.ClientId, Amount = operation.Amount, Currency = asset.Name, DateTime = msg.Date, OpType = "CashInOut", CustomData = JsonConvert.SerializeObject(operation) }; try { await _cashOperationsRepository.RegisterAsync(operation) .ContinueWith(t => _historyWriter.Push(newHistoryEntry)); } catch (Exception e) { await _log.WriteErrorAsync(nameof(CashInOutQueue), nameof(ProcessManualOperation), null, e); return(false); } return(true); }
public async Task ChangeBalance(ClientWalletEntity wallet, Asset asset, decimal amount, string comment) { var operationId = Guid.NewGuid().ToString("N"); var request = new CashInOutOperation { BrokerId = wallet.Client.TenantId, AccountId = (ulong)wallet.Client.ClientId, WalletId = (ulong)wallet.WalletId, AssetId = asset.Symbol, Description = comment, Volume = amount.ToString(CultureInfo.InvariantCulture), Id = operationId }; _logger.LogInformation($"CashInRequest: {request.ToJson()}"); var response = await _matchingEngineClient.CashOperations.CashInOutAsync(request); _logger.LogInformation( "ME operations {MeOperation}, Id: {OperationId}. Status: {MeStatus}, Reason: {MeReason}; BrokerId: {TenantId}; AccountId: {AccountId}; WalletId: {WalletId}; Asset: {AssetSymbol}; Volume: {Volume}", "CashInOut", operationId, response.Status.ToString(), response.StatusReason, wallet.Client.TenantId, (ulong)wallet.Client.ClientId, (ulong)wallet.WalletId, asset.Symbol, amount); if (response.Status != Status.Ok) { throw new MatchingEngineException(response.Status.ToString(), response.StatusReason, "CashInOutAsync", "CashOperations", request, response); } }
public async Task <OperationResponse> CashInAsync(string brokerId, CashInOutModel model) { var wallet = await _accountsClient.Wallet.GetAsync((long)model.WalletId, brokerId); if (wallet == null) { throw new ArgumentException($"Wallet '{model.WalletId}' does not exist."); } if (!wallet.IsEnabled) { throw new ArgumentException($"Wallet '{model.WalletId}' is disabled."); } if (wallet.Type != WalletType.Main) { throw new ArgumentException($"Wallet type must have type '{WalletType.Main}' for deposit / withdrawal operations."); } var request = new CashInOutOperation { Id = Guid.NewGuid().ToString(), BrokerId = brokerId, AccountId = model.AccountId, WalletId = model.WalletId, AssetId = model.Asset, Volume = model.Volume.ToString(CultureInfo.InvariantCulture), Description = model.Description }; var fee = await GetFeeAsync(brokerId, model.Asset, RequestType.CashIn); request.Fees.Add(fee); var result = await _matchingEngineClient.CashOperations.CashInOutAsync(request); return(new OperationResponse(result)); }
async Task <CashInOutOperationResponse> ICashServiceClient.CashInOutAsync(CashInOutOperation request, CancellationToken cancellationToken) { return(await CashInOutAsync(request, cancellationToken : cancellationToken)); }
CashInOutOperationResponse ICashServiceClient.CashInOut(CashInOutOperation request, CancellationToken cancellationToken) { return(CashInOut(request, cancellationToken: cancellationToken)); }
public async Task <Response> CashInOutAsync(CashInOutOperation request, CancellationToken cancellationToken = default) { return(await _client.CashInOutAsync(request, cancellationToken : cancellationToken)); }
public static void AddFeeDataToOperation(this CashInOutOperation operation, CashInOutQueueMessage message) { operation.FeeSize = (double)(message?.Fees?.FirstOrDefault()?.Transfer?.Volume ?? 0); operation.FeeType = FeeType.Absolute; }
public CashInOutOperationResponse CashInOut(CashInOutOperation request, CancellationToken cancellationToken = new CancellationToken()) { throw new System.NotImplementedException(); }