Example #1
0
        private async Task HandleInitiateAsync(ClientSwap swap, ClientSwap clientSwap)
        {
            if (swap.SecretHash != null)
            {
                if (!swap.SecretHash.SequenceEqual(clientSwap.SecretHash))
                {
                    throw new InternalException(
                              code: Errors.InvalidSecretHash,
                              description: $"Secret hash does not match the one already received for swap {swap.Id}");
                }
                return;
            }

            if (clientSwap.SecretHash == null || clientSwap.SecretHash.Length != CurrencySwap.DefaultSecretHashSize)
            {
                throw new InternalException(
                          code: Errors.InvalidSecretHash,
                          description: $"Incorrect secret hash length for swap {swap.Id}");
            }

            Log.Debug("Secret hash {@hash} successfully received", clientSwap.SecretHash.ToHexString());

            swap.SecretHash = clientSwap.SecretHash;
            RaiseSwapUpdated(swap, SwapStateFlags.HasSecretHash);

            // check party requisites
            if (clientSwap.PartyAddress == null)
            {
                throw new InternalException(
                          code: Errors.InvalidWallets,
                          description: $"Incorrect party address for swap {swap.Id}");
            }

            //if (IsCriminal(clientSwap.PartyAddress))
            //    throw new InternalException(
            //        code: Errors.IsCriminalWallet,
            //        description: $"Party wallet is criminal for swap {swap.Id}");

            if (clientSwap.RewardForRedeem < 0)
            {
                throw new InternalException(
                          code: Errors.InvalidRewardForRedeem,
                          description: $"Incorrect reward for redeem for swap {swap.Id}");
            }

            swap.PartyAddress         = clientSwap.PartyAddress;
            swap.PartyRewardForRedeem = clientSwap.PartyRewardForRedeem;

            // create self requisites
            swap.ToAddress = (await _account
                              .GetRedeemAddressAsync(swap.PurchasedCurrency)
                              .ConfigureAwait(false))
                             .Address;

            var purchasedCurrencyBalance = await _account
                                           .GetBalanceAsync(swap.PurchasedCurrency)
                                           .ConfigureAwait(false);

            swap.RewardForRedeem = purchasedCurrencyBalance.Available < swap.PurchasedCurrency.GetDefaultRedeemFee() &&
                                   !(swap.PurchasedCurrency is BitcoinBasedCurrency)
                ? swap.PurchasedCurrency.GetDefaultRedeemFee() * 2
                : 0;

            RaiseSwapUpdated(swap, SwapStateFlags.Empty);

            // send "accept" to other side
            _swapClient.SwapAcceptAsync(swap);

            await GetCurrencySwap(swap.PurchasedCurrency)
            .PrepareToReceiveAsync(swap)
            .ConfigureAwait(false);
        }
Example #2
0
        private async Task <Error> HandleInitiateAsync(
            Swap swap,
            Swap receivedSwap,
            CancellationToken cancellationToken = default)
        {
            if (DateTime.UtcNow > swap.TimeStamp.ToUniversalTime() + DefaultCredentialsExchangeTimeout)
            {
                Log.Error("Handle initiate after swap {@swap} timeout", swap.Id);

                swap.StateFlags |= SwapStateFlags.IsCanceled;

                await UpdateSwapAsync(swap, SwapStateFlags.IsCanceled, cancellationToken)
                .ConfigureAwait(false);

                return(null); // no error
            }

            // check secret hash
            if (swap.SecretHash != null &&
                !swap.SecretHash.SequenceEqual(receivedSwap.SecretHash))
            {
                return(new Error(Errors.InvalidSecretHash, $"Secret hash does not match the one already received for swap {swap.Id}"));
            }

            if (receivedSwap.SecretHash == null ||
                receivedSwap.SecretHash.Length != CurrencySwap.DefaultSecretHashSize)
            {
                return(new Error(Errors.InvalidSecretHash, $"Incorrect secret hash length for swap {swap.Id}"));
            }

            Log.Debug("Secret hash {@hash} successfully received", receivedSwap.SecretHash.ToHexString());

            swap.SecretHash = receivedSwap.SecretHash;

            await UpdateSwapAsync(swap, SwapStateFlags.HasSecretHash, cancellationToken)
            .ConfigureAwait(false);

            // check party address
            if (receivedSwap.PartyAddress == null)
            {
                return(new Error(Errors.InvalidWallets, $"Incorrect party address for swap {swap.Id}"));
            }

            // check party reward for redeem
            if (receivedSwap.RewardForRedeem < 0)
            {
                return(new Error(Errors.InvalidRewardForRedeem, $"Incorrect reward for redeem for swap {swap.Id}"));
            }

            if (swap.PartyAddress == null)
            {
                swap.PartyAddress = receivedSwap.PartyAddress;
            }

            if (swap.PartyRewardForRedeem == 0 && receivedSwap.PartyRewardForRedeem > 0)
            {
                swap.PartyRewardForRedeem = receivedSwap.PartyRewardForRedeem;
            }

            if (swap.PartyRefundAddress == null)
            {
                swap.PartyRefundAddress = receivedSwap.PartyRefundAddress;
            }

            var redeemFromWalletAddress = swap.RedeemFromAddress != null
                ? await _account
                                          .GetAddressAsync(swap.PurchasedCurrency, swap.RedeemFromAddress, cancellationToken)
                                          .ConfigureAwait(false)
                : null;

            var purchasedCurrency = _account.Currencies.GetByName(swap.PurchasedCurrency);

            swap.RewardForRedeem = await RewardForRedeemHelper
                                   .EstimateAsync(
                account : _account,
                quotesProvider : _quotesProvider,
                feeCurrencyQuotesProvider : symbol => _marketDataRepository
                ?.OrderBookBySymbol(symbol)
                ?.TopOfBook(),
                redeemableCurrency : purchasedCurrency,
                redeemFromAddress : redeemFromWalletAddress,
                cancellationToken : cancellationToken)
                                   .ConfigureAwait(false);

            var soldCurrency = _account.Currencies.GetByName(swap.SoldCurrency);

            // select refund address for bitcoin based currency
            if (soldCurrency is BitcoinBasedConfig && swap.RefundAddress == null)
            {
                swap.RefundAddress = (await _account
                                      .GetCurrencyAccount <BitcoinBasedAccount>(soldCurrency.Name)
                                      .GetRefundAddressAsync(cancellationToken)
                                      .ConfigureAwait(false))
                                     ?.Address;
            }

            await UpdateSwapAsync(swap, SwapStateFlags.Empty, cancellationToken)
            .ConfigureAwait(false);

            // send "accept" to other side
            _swapClient.SwapAcceptAsync(swap);

            await GetCurrencySwap(swap.PurchasedCurrency)
            .StartPartyPaymentControlAsync(swap, cancellationToken)
            .ConfigureAwait(false);

            return(null); // no error
        }
Example #3
0
        private async Task HandleInitiateAsync(Swap swap, Swap receivedSwap)
        {
            if (DateTime.UtcNow > swap.TimeStamp.ToUniversalTime() + DefaultCredentialsExchangeTimeout)
            {
                Log.Error("Handle initiate after swap {@swap} timeout", swap.Id);

                swap.Cancel();
                RaiseSwapUpdated(swap, SwapStateFlags.IsCanceled);

                return;
            }

            if (swap.SecretHash != null)
            {
                if (!swap.SecretHash.SequenceEqual(receivedSwap.SecretHash))
                {
                    throw new InternalException(
                              code: Errors.InvalidSecretHash,
                              description: $"Secret hash does not match the one already received for swap {swap.Id}");
                }
                return;
            }

            if (receivedSwap.SecretHash == null || receivedSwap.SecretHash.Length != CurrencySwap.DefaultSecretHashSize)
            {
                throw new InternalException(
                          code: Errors.InvalidSecretHash,
                          description: $"Incorrect secret hash length for swap {swap.Id}");
            }

            Log.Debug("Secret hash {@hash} successfully received", receivedSwap.SecretHash.ToHexString());

            swap.SecretHash = receivedSwap.SecretHash;
            RaiseSwapUpdated(swap, SwapStateFlags.HasSecretHash);

            // check party requisites
            if (receivedSwap.PartyAddress == null)
            {
                throw new InternalException(
                          code: Errors.InvalidWallets,
                          description: $"Incorrect party address for swap {swap.Id}");
            }

            //if (IsCriminal(clientSwap.PartyAddress))
            //    throw new InternalException(
            //        code: Errors.IsCriminalWallet,
            //        description: $"Party wallet is criminal for swap {swap.Id}");

            if (receivedSwap.RewardForRedeem < 0)
            {
                throw new InternalException(
                          code: Errors.InvalidRewardForRedeem,
                          description: $"Incorrect reward for redeem for swap {swap.Id}");
            }

            swap.PartyAddress         = receivedSwap.PartyAddress;
            swap.PartyRewardForRedeem = receivedSwap.PartyRewardForRedeem;

            // create self requisites
            var walletToAddress = (await _account
                                   .GetRedeemAddressAsync(swap.PurchasedCurrency)
                                   .ConfigureAwait(false));

            swap.ToAddress = walletToAddress.Address;

            swap.RewardForRedeem = await GetRewardForRedeemAsync(walletToAddress)
                                   .ConfigureAwait(false);

            RaiseSwapUpdated(swap, SwapStateFlags.Empty);

            // send "accept" to other side
            _swapClient.SwapAcceptAsync(swap);

            await GetCurrencySwap(swap.PurchasedCurrency)
            .StartPartyPaymentControlAsync(swap)
            .ConfigureAwait(false);
        }