public void Sign_And_Verify() { // arrange var data = "Test string."; // act var keyPair = _service.GenerateKeyPairPem(); var signature = _service.GenerateSignature(Encoding.UTF8.GetBytes(data), keyPair.GetPrivateKey()); var isValid = _service.VerifySignature(Encoding.UTF8.GetBytes(data), signature, keyPair.GetPublicKey()); // assert Assert.True(isValid); }
public async Task <CommandHandlingResult> Handle(StartCashoutCommand command, IEventPublisher eventPublisher) { var operationId = command.OperationId.ToString(); _log.Info("Got cashout command", context: new { operationId, command = command.ToJson() }); var clientId = command.ClientId.ToString(); long?accountId = null; string walletId; if (command.WalletId.HasValue) { walletId = command.WalletId.Value == Guid.Empty ? clientId : command.WalletId.Value.ToString(); } else { walletId = clientId; } var accountSearchResponse = await _siriusApiClient.Accounts.SearchAsync(new AccountSearchRequest { BrokerAccountId = _brokerAccountId, UserNativeId = clientId, ReferenceId = walletId }); if (accountSearchResponse.ResultCase == AccountSearchResponse.ResultOneofCase.Error) { var message = "Error fetching Sirius Account"; _log.Warning(nameof(CashoutCommandHandler), message, context: new { error = accountSearchResponse.Error, walletId, clientId, operationId }); throw new Exception(message); } if (!accountSearchResponse.Body.Items.Any()) { var accountRequestId = $"{_brokerAccountId}_{walletId}_account"; var userRequestId = $"{clientId}_user"; var userCreateResponse = await _siriusApiClient.Users.CreateAsync(new CreateUserRequest { RequestId = userRequestId, NativeId = clientId }); if (userCreateResponse.BodyCase == CreateUserResponse.BodyOneofCase.Error) { var message = "Error creating User in Sirius"; _log.Warning(nameof(CashoutCommandHandler), message, context: new { error = userCreateResponse.Error, clientId, requestId = userRequestId, operationId }); throw new Exception(message); } var createResponse = await _siriusApiClient.Accounts.CreateAsync(new AccountCreateRequest { RequestId = accountRequestId, BrokerAccountId = _brokerAccountId, UserId = userCreateResponse.User.Id, ReferenceId = walletId }); if (createResponse.ResultCase == AccountCreateResponse.ResultOneofCase.Error) { var message = "Error creating user in Sirius"; _log.Warning(nameof(CashoutCommandHandler), message, context: new { error = createResponse.Error, clientId, requestId = accountRequestId, operationId }); throw new Exception(message); } accountId = createResponse.Body.Account.Id; } else { accountId = accountSearchResponse.Body.Items.FirstOrDefault()?.Id; } var whitelistingRequestId = $"lykke:trading_wallet:{clientId}"; var whitelistItemCreateResponse = await _siriusApiClient.WhitelistItems.CreateAsync(new WhitelistItemCreateRequest { Name = "Trading Wallet Whitelist", Scope = new WhitelistItemScope { BrokerAccountId = _brokerAccountId, AccountId = accountId, UserNativeId = clientId }, Details = new WhitelistItemDetails { TransactionType = WhitelistTransactionType.Any, TagType = new NullableWhitelistItemTagType { Null = NullValue.NullValue } }, Lifespan = new WhitelistItemLifespan { StartsAt = Timestamp.FromDateTime(DateTime.UtcNow) }, RequestId = whitelistingRequestId }); if (whitelistItemCreateResponse.BodyCase == WhitelistItemCreateResponse.BodyOneofCase.Error) { _log.Warning(nameof(CashoutCommandHandler), "Error creating Whitelist item", context: new { error = whitelistItemCreateResponse.Error, clientId, requestId = whitelistingRequestId, operationId }); throw new Exception("Error creating Whitelist item"); } var tag = !string.IsNullOrWhiteSpace(command.Tag) ? command.Tag : string.Empty; WithdrawalDestinationTagType?tagType = !string.IsNullOrWhiteSpace(command.Tag) ? (long.TryParse(command.Tag, out _) ? WithdrawalDestinationTagType.Number : WithdrawalDestinationTagType.Text) : null; var document = new WithdrawalDocument { BrokerAccountId = _brokerAccountId, WithdrawalReferenceId = command.OperationId.ToString(), AssetId = command.SiriusAssetId, Amount = command.Amount, DestinationDetails = new WithdrawalDestinationDetails { Address = command.Address, Tag = tag, TagType = tagType }, AccountReferenceId = walletId }.ToJson(); var signatureBytes = _encryptionService.GenerateSignature(Encoding.UTF8.GetBytes(document), _privateKeyService.GetPrivateKey()); var signature = Convert.ToBase64String(signatureBytes); var result = await _siriusApiClient.Withdrawals.ExecuteAsync(new WithdrawalExecuteRequest { RequestId = $"{_brokerAccountId}_{command.OperationId}", Document = document, Signature = signature }); if (result.ResultCase == WithdrawalExecuteResponse.ResultOneofCase.Error) { switch (result.Error.ErrorCode) { case WithdrawalExecuteErrorResponseBody.Types.ErrorCode.IsNotAuthorized: case WithdrawalExecuteErrorResponseBody.Types.ErrorCode.Unknown: LogError(operationId, result.Error); return(CommandHandlingResult.Fail(TimeSpan.FromSeconds(10))); case WithdrawalExecuteErrorResponseBody.Types.ErrorCode.InvalidParameters: case WithdrawalExecuteErrorResponseBody.Types.ErrorCode.NotFound: LogError(operationId, result.Error); return(CommandHandlingResult.Ok()); // abort case WithdrawalExecuteErrorResponseBody.Types.ErrorCode.NotEnoughBalance: LogWarning(operationId, result.Error); return(CommandHandlingResult.Fail(TimeSpan.FromSeconds(_notEnoughBalanceRetryDelayInSeconds))); case WithdrawalExecuteErrorResponseBody.Types.ErrorCode.InvalidAddress: case WithdrawalExecuteErrorResponseBody.Types.ErrorCode.AmountIsTooLow: LogWarning(operationId, result.Error); return(CommandHandlingResult.Ok()); // abort } } _log.Info("Cashout sent to Sirius", context: new { operationId, withdrawal = result.Body.Withdrawal.ToJson() }); return(CommandHandlingResult.Ok()); }