Exemple #1
0
        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);
        }
Exemple #2
0
        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());
        }