Пример #1
0
        public async Task ElementsAssetsAreHandledCorrectly()
        {
            using (var tester = ServerTester.Create())
            {
                tester.ActivateLBTC();
                await tester.StartAsync();

                var user = tester.NewAccount();
                user.GrantAccess();
                user.RegisterDerivationScheme("LBTC");
                user.RegisterDerivationScheme("USDT");

                //no tether on our regtest, lets create it and set it
                var tether           = tester.NetworkProvider.GetNetwork <ElementsBTCPayNetwork>("USDT");
                var lbtc             = tester.NetworkProvider.GetNetwork <ElementsBTCPayNetwork>("LBTC");
                var issueAssetResult = await tester.LBTCExplorerNode.SendCommandAsync("issueasset", 100000, 0);

                tether.AssetId = uint256.Parse(issueAssetResult.Result["asset"].ToString());
                ((ElementsBTCPayNetwork)tester.PayTester.GetService <BTCPayWalletProvider>().GetWallet("USDT").Network)
                .AssetId = tether.AssetId;
                Logs.Tester.LogInformation($"Asset is {tether.AssetId}");
                Assert.Equal(tether.AssetId, tester.NetworkProvider.GetNetwork <ElementsBTCPayNetwork>("USDT").AssetId);
                Assert.Equal(tether.AssetId, ((ElementsBTCPayNetwork)tester.PayTester.GetService <BTCPayWalletProvider>().GetWallet("USDT").Network).AssetId);
                //test: register 2 assets on the same elements network and make sure paying an invoice on one does not affect the other in any way
                var invoice = await user.BitPay.CreateInvoiceAsync(new Invoice(0.1m, "BTC"));

                Assert.Equal(2, invoice.SupportedTransactionCurrencies.Count);
                var ci = invoice.CryptoInfo.Single(info => info.CryptoCode.Equals("LBTC"));
                //1 lbtc = 1 btc
                Assert.Equal(1, ci.Rate);
                var star = await tester.LBTCExplorerNode.SendCommandAsync("sendtoaddress", ci.Address, ci.Due, "", "", false, true,
                                                                          1, "UNSET", lbtc.AssetId);

                TestUtils.Eventually(() =>
                {
                    var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
                    Assert.Equal("paid", localInvoice.Status);
                    Assert.Single(localInvoice.CryptoInfo.Single(info => info.CryptoCode.Equals("LBTC")).Payments);
                });

                invoice = await user.BitPay.CreateInvoiceAsync(new Invoice(0.1m, "BTC"));

                ci = invoice.CryptoInfo.Single(info => info.CryptoCode.Equals("USDT"));
                Assert.Equal(2, invoice.SupportedTransactionCurrencies.Count);
                star = await tester.LBTCExplorerNode.SendCommandAsync("sendtoaddress", ci.Address, ci.Due, "", "", false, true,
                                                                      1, "UNSET", tether.AssetId);

                TestUtils.Eventually(() =>
                {
                    var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
                    Assert.Equal("paid", localInvoice.Status);
                    Assert.Single(localInvoice.CryptoInfo.Single(info => info.CryptoCode.Equals("USDT", StringComparison.InvariantCultureIgnoreCase)).Payments);
                });
            }
        }
Пример #2
0
        public async Task CanUseJSModal()
        {
            using (var s = SeleniumTester.Create())
            {
                await s.StartAsync();

                s.GoToRegister();
                s.RegisterNewUser();
                var store = s.CreateNewStore();
                s.GoToStore(store.storeId);
                s.AddDerivationScheme();
                var invoiceId = s.CreateInvoice(store.storeId, 0.001m, "BTC", "*****@*****.**");
                var invoice   = await s.Server.PayTester.InvoiceRepository.GetInvoice(invoiceId);

                s.Driver.Navigate()
                .GoToUrl(new Uri(s.Server.PayTester.ServerUri, $"tests/index.html?invoice={invoiceId}"));
                TestUtils.Eventually(() =>
                {
                    Assert.True(s.Driver.FindElement(By.Name("btcpay")).Displayed);
                });
                await s.Server.ExplorerNode.SendToAddressAsync(BitcoinAddress.Create(invoice
                                                                                     .GetPaymentMethod(new PaymentMethodId("BTC", PaymentTypes.BTCLike))
                                                                                     .GetPaymentMethodDetails().GetPaymentDestination(), Network.RegTest),
                                                               new Money(0.001m, MoneyUnit.BTC));

                IWebElement closebutton = null;
                TestUtils.Eventually(() =>
                {
                    var frameElement = s.Driver.FindElement(By.Name("btcpay"));
                    var iframe       = s.Driver.SwitchTo().Frame(frameElement);
                    closebutton      = iframe.FindElement(By.ClassName("close-action"));
                    Assert.True(closebutton.Displayed);
                });
                closebutton.Click();
                s.Driver.AssertElementNotFound(By.Name("btcpay"));
                Assert.Equal(s.Driver.Url,
                             new Uri(s.Server.PayTester.ServerUri, $"tests/index.html?invoice={invoiceId}").ToString());
            }
        }
Пример #3
0
        public async Task CanUsePullPaymentsViaUI()
        {
            using (var s = SeleniumTester.Create())
            {
                await s.StartAsync();

                s.RegisterNewUser(true);
                var receiver     = s.CreateNewStore();
                var receiverSeed = s.GenerateWallet("BTC", "", true, true, ScriptPubKeyType.Segwit);
                await s.Server.ExplorerNode.GenerateAsync(1);

                await s.FundStoreWallet(denomination : 50.0m);

                s.GoToWallet(navPages: WalletsNavPages.PullPayments);
                s.Driver.FindElement(By.Id("NewPullPayment")).Click();
                s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
                s.Driver.FindElement(By.Id("Amount")).Clear();
                s.Driver.FindElement(By.Id("Amount")).SendKeys("99.0" + Keys.Enter);
                s.Driver.FindElement(By.LinkText("View")).Click();

                Thread.Sleep(1000);
                s.GoToWallet(navPages: WalletsNavPages.PullPayments);
                s.Driver.FindElement(By.Id("NewPullPayment")).Click();
                s.Driver.FindElement(By.Id("Name")).SendKeys("PP2");
                s.Driver.FindElement(By.Id("Amount")).Clear();
                s.Driver.FindElement(By.Id("Amount")).SendKeys("100.0" + Keys.Enter);
                // This should select the first View, ie, the last one PP2
                s.Driver.FindElement(By.LinkText("View")).Click();

                Thread.Sleep(1000);
                var address = await s.Server.ExplorerNode.GetNewAddressAsync();

                s.Driver.FindElement(By.Id("Destination")).SendKeys(address.ToString());
                s.Driver.FindElement(By.Id("ClaimedAmount")).Clear();
                s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys("15" + Keys.Enter);
                s.AssertHappyMessage();

                // We should not be able to use an address already used
                s.Driver.FindElement(By.Id("Destination")).SendKeys(address.ToString());
                s.Driver.FindElement(By.Id("ClaimedAmount")).Clear();
                s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys("20" + Keys.Enter);
                s.AssertHappyMessage(StatusMessageModel.StatusSeverity.Error);

                address = await s.Server.ExplorerNode.GetNewAddressAsync();

                s.Driver.FindElement(By.Id("Destination")).Clear();
                s.Driver.FindElement(By.Id("Destination")).SendKeys(address.ToString());
                s.Driver.FindElement(By.Id("ClaimedAmount")).Clear();
                s.Driver.FindElement(By.Id("ClaimedAmount")).SendKeys("20" + Keys.Enter);
                s.AssertHappyMessage();
                Assert.Contains("AwaitingApproval", s.Driver.PageSource);

                var viewPullPaymentUrl = s.Driver.Url;
                // This one should have nothing
                s.GoToWallet(navPages: WalletsNavPages.PullPayments);
                var payouts = s.Driver.FindElements(By.ClassName("pp-payout"));
                Assert.Equal(2, payouts.Count);
                payouts[1].Click();
                Assert.Contains("No payout waiting for approval", s.Driver.PageSource);

                // PP2 should have payouts
                s.GoToWallet(navPages: WalletsNavPages.PullPayments);
                payouts = s.Driver.FindElements(By.ClassName("pp-payout"));
                payouts[0].Click();
                Assert.DoesNotContain("No payout waiting for approval", s.Driver.PageSource);
                s.Driver.FindElement(By.Id("selectAllCheckbox")).Click();
                s.Driver.FindElement(By.Id("payCommand")).Click();
                s.Driver.ScrollTo(By.Id("SendMenu"));
                s.Driver.FindElement(By.Id("SendMenu")).ForceClick();
                s.Driver.FindElement(By.CssSelector("button[value=nbx-seed]")).Click();
                s.Driver.FindElement(By.CssSelector("button[value=broadcast]")).ForceClick();
                s.AssertHappyMessage();

                TestUtils.Eventually(() =>
                {
                    s.Driver.Navigate().Refresh();
                    Assert.Contains("badge transactionLabel", s.Driver.PageSource);
                });
                Assert.Equal("payout", s.Driver.FindElement(By.ClassName("transactionLabel")).Text);

                s.GoToWallet(navPages: WalletsNavPages.Payouts);
                TestUtils.Eventually(() =>
                {
                    s.Driver.Navigate().Refresh();
                    Assert.Contains("No payout waiting for approval", s.Driver.PageSource);
                });
                var txs = s.Driver.FindElements(By.ClassName("transaction-link"));
                Assert.Equal(2, txs.Count);

                s.Driver.Navigate().GoToUrl(viewPullPaymentUrl);
                txs = s.Driver.FindElements(By.ClassName("transaction-link"));
                Assert.Equal(2, txs.Count);
                Assert.Contains("InProgress", s.Driver.PageSource);


                await s.Server.ExplorerNode.GenerateAsync(1);

                TestUtils.Eventually(() =>
                {
                    s.Driver.Navigate().Refresh();
                    Assert.Contains("Completed", s.Driver.PageSource);
                });
                await s.Server.ExplorerNode.GenerateAsync(10);

                var pullPaymentId = viewPullPaymentUrl.Split('/').Last();

                await TestUtils.EventuallyAsync(async() =>
                {
                    using var ctx   = s.Server.PayTester.GetService <ApplicationDbContextFactory>().CreateContext();
                    var payoutsData = await ctx.Payouts.Where(p => p.PullPaymentDataId == pullPaymentId).ToListAsync();
                    Assert.True(payoutsData.All(p => p.State == Data.PayoutState.Completed));
                });
            }
        }
Пример #4
0
        public async Task ElementsAssetsAreHandledCorrectly()
        {
            using (var tester = CreateServerTester())
            {
                tester.ActivateLBTC();
                await tester.StartAsync();

                var user = tester.NewAccount();
                user.GrantAccess();
                user.RegisterDerivationScheme("LBTC");
                user.RegisterDerivationScheme("USDT");
                user.RegisterDerivationScheme("ETB");
                await tester.LBTCExplorerNode.GenerateAsync(4);

                //no tether on our regtest, lets create it and set it
                var tether           = tester.NetworkProvider.GetNetwork <ElementsBTCPayNetwork>("USDT");
                var lbtc             = tester.NetworkProvider.GetNetwork <ElementsBTCPayNetwork>("LBTC");
                var etb              = tester.NetworkProvider.GetNetwork <ElementsBTCPayNetwork>("ETB");
                var issueAssetResult = await tester.LBTCExplorerNode.SendCommandAsync("issueasset", 100000, 0);

                tether.AssetId = uint256.Parse(issueAssetResult.Result["asset"].ToString());
                ((ElementsBTCPayNetwork)tester.PayTester.GetService <BTCPayWalletProvider>().GetWallet("USDT").Network)
                .AssetId = tether.AssetId;
                Assert.Equal(tether.AssetId, tester.NetworkProvider.GetNetwork <ElementsBTCPayNetwork>("USDT").AssetId);
                Assert.Equal(tether.AssetId, ((ElementsBTCPayNetwork)tester.PayTester.GetService <BTCPayWalletProvider>().GetWallet("USDT").Network).AssetId);

                var issueAssetResult2 = await tester.LBTCExplorerNode.SendCommandAsync("issueasset", 100000, 0);

                etb.AssetId = uint256.Parse(issueAssetResult2.Result["asset"].ToString());
                ((ElementsBTCPayNetwork)tester.PayTester.GetService <BTCPayWalletProvider>().GetWallet("ETB").Network)
                .AssetId = etb.AssetId;


                //test: register 2 assets on the same elements network and make sure paying an invoice on one does not affect the other in any way
                var invoice = await user.BitPay.CreateInvoiceAsync(new Invoice(0.1m, "BTC"));

                Assert.Equal(3, invoice.SupportedTransactionCurrencies.Count);
                var ci = invoice.CryptoInfo.Single(info => info.CryptoCode.Equals("LBTC"));
                //1 lbtc = 1 btc
                Assert.Equal(1, ci.Rate);
                var star = await tester.LBTCExplorerNode.SendCommandAsync("sendtoaddress", ci.Address, ci.Due, "", "", false, true,
                                                                          1, "UNSET", lbtc.AssetId);

                TestUtils.Eventually(() =>
                {
                    var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
                    Assert.Equal("paid", localInvoice.Status);
                    Assert.Single(localInvoice.CryptoInfo.Single(info => info.CryptoCode.Equals("LBTC")).Payments);
                });

                invoice = await user.BitPay.CreateInvoiceAsync(new Invoice(0.1m, "BTC"));

                ci = invoice.CryptoInfo.Single(info => info.CryptoCode.Equals("USDT"));
                Assert.Equal(3, invoice.SupportedTransactionCurrencies.Count);
                star = await tester.LBTCExplorerNode.SendCommandAsync("sendtoaddress", ci.Address, ci.Due, "", "", false, true,
                                                                      1, "UNSET", tether.AssetId);

                TestUtils.Eventually(() =>
                {
                    var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant);
                    Assert.Equal("paid", localInvoice.Status);
                    Assert.Single(localInvoice.CryptoInfo.Single(info => info.CryptoCode.Equals("USDT", StringComparison.InvariantCultureIgnoreCase)).Payments);
                });

                //test precision based on https://github.com/ElementsProject/elements/issues/805#issuecomment-601277606
                var etbBip21 = new BitcoinUrlBuilder(invoice.CryptoInfo.Single(info => info.CryptoCode == "ETB").PaymentUrls.BIP21, etb.NBitcoinNetwork);
                //precision = 2, 1ETB  = 0.00000100
                Assert.Equal(100, etbBip21.Amount.Satoshi);

                var lbtcBip21 = new BitcoinUrlBuilder(invoice.CryptoInfo.Single(info => info.CryptoCode == "LBTC").PaymentUrls.BIP21, lbtc.NBitcoinNetwork);
                //precision = 8, 0.1 = 0.1
                Assert.Equal(0.1m, lbtcBip21.Amount.ToDecimal(MoneyUnit.BTC));
            }
        }
Пример #5
0
        public async Task CanPayWithTwoCurrencies()
        {
            using (var tester = CreateServerTester())
            {
                tester.ActivateLTC();
                await tester.StartAsync();

                var user = tester.NewAccount();
                user.GrantAccess();
                user.RegisterDerivationScheme("BTC");
                // First we try payment with a merchant having only BTC
                var invoice = user.BitPay.CreateInvoice(
                    new Invoice()
                {
                    Price             = 5000.0m,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some description",
                    FullNotifications = true
                }, Facade.Merchant);

                var cashCow = tester.ExplorerNode;
                cashCow.Generate(2); // get some money in case
                var invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network);
                var firstPayment   = Money.Coins(0.04m);
                cashCow.SendToAddress(invoiceAddress, firstPayment);
                TestUtils.Eventually(() =>
                {
                    invoice = user.BitPay.GetInvoice(invoice.Id);
                    Assert.True(invoice.BtcPaid == firstPayment);
                });

                Assert.Single(invoice.CryptoInfo); // Only BTC should be presented

                var controller = tester.PayTester.GetController <UIInvoiceController>(null);
                var checkout   =
                    (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id, null)
                                                          .GetAwaiter().GetResult()).Value;
                Assert.Single(checkout.AvailableCryptos);
                Assert.Equal("BTC", checkout.CryptoCode);

                Assert.Single(invoice.PaymentCodes);
                Assert.Single(invoice.SupportedTransactionCurrencies);
                Assert.Single(invoice.SupportedTransactionCurrencies);
                Assert.Single(invoice.PaymentSubtotals);
                Assert.Single(invoice.PaymentTotals);
                Assert.True(invoice.PaymentCodes.ContainsKey("BTC"));
                Assert.True(invoice.SupportedTransactionCurrencies.ContainsKey("BTC"));
                Assert.True(invoice.SupportedTransactionCurrencies["BTC"].Enabled);
                Assert.True(invoice.PaymentSubtotals.ContainsKey("BTC"));
                Assert.True(invoice.PaymentTotals.ContainsKey("BTC"));
                //////////////////////

                // Retry now with LTC enabled
                user.RegisterDerivationScheme("LTC");
                invoice = user.BitPay.CreateInvoice(
                    new Invoice()
                {
                    Price             = 5000.0m,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some description",
                    FullNotifications = true
                }, Facade.Merchant);

                cashCow        = tester.ExplorerNode;
                invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network);
                firstPayment   = Money.Coins(0.04m);
                cashCow.SendToAddress(invoiceAddress, firstPayment);
                TestLogs.LogInformation("First payment sent to " + invoiceAddress);
                TestUtils.Eventually(() =>
                {
                    invoice = user.BitPay.GetInvoice(invoice.Id);
                    Assert.True(invoice.BtcPaid == firstPayment);
                });

                cashCow = tester.LTCExplorerNode;
                var ltcCryptoInfo = invoice.CryptoInfo.FirstOrDefault(c => c.CryptoCode == "LTC");
                Assert.NotNull(ltcCryptoInfo);
                invoiceAddress = BitcoinAddress.Create(ltcCryptoInfo.Address, cashCow.Network);
                var secondPayment = Money.Coins(decimal.Parse(ltcCryptoInfo.Due, CultureInfo.InvariantCulture));
                cashCow.Generate(4); // LTC is not worth a lot, so just to make sure we have money...
                cashCow.SendToAddress(invoiceAddress, secondPayment);
                TestLogs.LogInformation("Second payment sent to " + invoiceAddress);
                TestUtils.Eventually(() =>
                {
                    invoice = user.BitPay.GetInvoice(invoice.Id);
                    Assert.Equal(Money.Zero, invoice.BtcDue);
                    var ltcPaid = invoice.CryptoInfo.First(c => c.CryptoCode == "LTC");
                    Assert.Equal(Money.Zero, ltcPaid.Due);
                    Assert.Equal(secondPayment, ltcPaid.CryptoPaid);
                    Assert.Equal("paid", invoice.Status);
                    Assert.False((bool)((JValue)invoice.ExceptionStatus).Value);
                });

                controller = tester.PayTester.GetController <UIInvoiceController>(null);
                checkout   = (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id, "LTC")
                                                                   .GetAwaiter().GetResult()).Value;
                Assert.Equal(2, checkout.AvailableCryptos.Count);
                Assert.Equal("LTC", checkout.CryptoCode);


                Assert.Equal(2, invoice.PaymentCodes.Count());
                Assert.Equal(2, invoice.SupportedTransactionCurrencies.Count());
                Assert.Equal(2, invoice.SupportedTransactionCurrencies.Count());
                Assert.Equal(2, invoice.PaymentSubtotals.Count());
                Assert.Equal(2, invoice.PaymentTotals.Count());
                Assert.True(invoice.PaymentCodes.ContainsKey("LTC"));
                Assert.True(invoice.SupportedTransactionCurrencies.ContainsKey("LTC"));
                Assert.True(invoice.SupportedTransactionCurrencies["LTC"].Enabled);
                Assert.True(invoice.PaymentSubtotals.ContainsKey("LTC"));
                Assert.True(invoice.PaymentTotals.ContainsKey("LTC"));


                // Check if we can disable LTC
                invoice = user.BitPay.CreateInvoice(
                    new Invoice()
                {
                    Price             = 5000.0m,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some description",
                    FullNotifications = true,
                    SupportedTransactionCurrencies = new Dictionary <string, InvoiceSupportedTransactionCurrency>()
                    {
                        { "BTC", new InvoiceSupportedTransactionCurrency()
                          {
                              Enabled = true
                          } }
                    }
                }, Facade.Merchant);

                Assert.Single(invoice.CryptoInfo.Where(c => c.CryptoCode == "BTC"));
                Assert.Empty(invoice.CryptoInfo.Where(c => c.CryptoCode == "LTC"));
            }
        }
Пример #6
0
        public async Task CanSetupWallet()
        {
            using (var tester = CreateServerTester())
            {
                tester.ActivateLTC();
                tester.ActivateLightning();
                await tester.StartAsync();

                var user       = tester.NewAccount();
                var cryptoCode = "BTC";
                await user.GrantAccessAsync(true);

                user.RegisterDerivationScheme(cryptoCode);
                user.RegisterDerivationScheme("LTC");
                user.RegisterLightningNode(cryptoCode, LightningConnectionType.CLightning);
                var btcNetwork = tester.PayTester.Networks.GetNetwork <BTCPayNetwork>(cryptoCode);
                var invoice    = await user.BitPay.CreateInvoiceAsync(
                    new Invoice
                {
                    Price             = 1.5m,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some description",
                    FullNotifications = true
                }, Facade.Merchant);

                Assert.Equal(3, invoice.CryptoInfo.Length);

                // Setup Lightning
                var controller  = user.GetController <UIStoresController>();
                var lightningVm = (LightningNodeViewModel)Assert.IsType <ViewResult>(await controller.SetupLightningNode(user.StoreId, cryptoCode)).Model;
                Assert.True(lightningVm.Enabled);
                var response = await controller.SetLightningNodeEnabled(user.StoreId, cryptoCode, false);

                Assert.IsType <RedirectToActionResult>(response);

                // Get enabled state from settings
                LightningSettingsViewModel lnSettingsModel;
                response        = controller.LightningSettings(user.StoreId, cryptoCode).GetAwaiter().GetResult();
                lnSettingsModel = (LightningSettingsViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.NotNull(lnSettingsModel?.ConnectionString);
                Assert.False(lnSettingsModel.Enabled);

                // Setup wallet
                WalletSetupViewModel setupVm;
                var storeId = user.StoreId;
                response = await controller.GenerateWallet(storeId, cryptoCode, WalletSetupMethod.GenerateOptions, new WalletSetupRequest());

                Assert.IsType <ViewResult>(response);

                // Get enabled state from settings
                response = controller.WalletSettings(user.StoreId, cryptoCode).GetAwaiter().GetResult();
                var onchainSettingsModel = (WalletSettingsViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.NotNull(onchainSettingsModel?.DerivationScheme);
                Assert.True(onchainSettingsModel.Enabled);

                // Disable wallet
                onchainSettingsModel.Enabled = false;
                response = controller.UpdateWalletSettings(onchainSettingsModel).GetAwaiter().GetResult();
                Assert.IsType <RedirectToActionResult>(response);
                response             = controller.WalletSettings(user.StoreId, cryptoCode).GetAwaiter().GetResult();
                onchainSettingsModel = (WalletSettingsViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.NotNull(onchainSettingsModel?.DerivationScheme);
                Assert.False(onchainSettingsModel.Enabled);

                var oldScheme = onchainSettingsModel.DerivationScheme;

                invoice = await user.BitPay.CreateInvoiceAsync(
                    new Invoice
                {
                    Price             = 1.5m,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some description",
                    FullNotifications = true
                }, Facade.Merchant);

                Assert.Single(invoice.CryptoInfo);
                Assert.Equal("LTC", invoice.CryptoInfo[0].CryptoCode);

                // Removing the derivation scheme, should redirect to store page
                response = controller.ConfirmDeleteWallet(user.StoreId, cryptoCode).GetAwaiter().GetResult();
                Assert.IsType <RedirectToActionResult>(response);

                // Setting it again should show the confirmation page
                response = await controller.UpdateWallet(new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode, DerivationScheme = oldScheme });

                setupVm = (WalletSetupViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.True(setupVm.Confirmation);

                // The following part posts a wallet update, confirms it and checks the result

                // cobo vault file
                var content = "{\"ExtPubKey\":\"xpub6CEqRFZ7yZxCFXuEWZBAdnC8bdvu9SRHevaoU2SsW9ZmKhrCShmbpGZWwaR15hdLURf8hg47g4TpPGaqEU8hw5LEJCE35AUhne67XNyFGBk\",\"MasterFingerprint\":\"7a7563b5\",\"DerivationPath\":\"M\\/84'\\/0'\\/0'\",\"CoboVaultFirmwareVersion\":\"1.2.0(BTC-Only)\"}";
                response = await controller.UpdateWallet(new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode, WalletFile = TestUtils.GetFormFile("cobovault.json", content) });

                setupVm = (WalletSetupViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.True(setupVm.Confirmation);
                response = await controller.UpdateWallet(setupVm);

                Assert.IsType <RedirectToActionResult>(response);
                response = await controller.WalletSettings(storeId, cryptoCode);

                var settingsVm = (WalletSettingsViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.Equal("CoboVault", settingsVm.Source);

                // wasabi wallet file
                content  = "{\r\n  \"EncryptedSecret\": \"6PYWBQ1zsukowsnTNA57UUx791aBuJusm7E4egXUmF5WGw3tcdG3cmTL57\",\r\n  \"ChainCode\": \"waSIVbn8HaoovoQg/0t8IS1+ZCxGsJRGFT21i06nWnc=\",\r\n  \"MasterFingerprint\": \"7a7563b5\",\r\n  \"ExtPubKey\": \"xpub6CEqRFZ7yZxCFXuEWZBAdnC8bdvu9SRHevaoU2SsW9ZmKhrCShmbpGZWwaR15hdLURf8hg47g4TpPGaqEU8hw5LEJCE35AUhne67XNyFGBk\",\r\n  \"PasswordVerified\": false,\r\n  \"MinGapLimit\": 21,\r\n  \"AccountKeyPath\": \"84'/0'/0'\",\r\n  \"BlockchainState\": {\r\n    \"Network\": \"RegTest\",\r\n    \"Height\": \"0\"\r\n  },\r\n  \"HdPubKeys\": []\r\n}";
                response = await controller.UpdateWallet(new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode, WalletFile = TestUtils.GetFormFile("wasabi.json", content) });

                setupVm = (WalletSetupViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.True(setupVm.Confirmation);
                response = await controller.UpdateWallet(setupVm);

                Assert.IsType <RedirectToActionResult>(response);
                response = await controller.WalletSettings(storeId, cryptoCode);

                settingsVm = (WalletSettingsViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.Equal("WasabiFile", settingsVm.Source);

                // Can we upload coldcard settings? (Should fail, we are giving a mainnet file to a testnet network)
                content  = "{\"keystore\": {\"ckcc_xpub\": \"xpub661MyMwAqRbcGVBsTGeNZN6QGVHmMHLdSA4FteGsRrEriu4pnVZMZWnruFFFXkMnyoBjyHndD3Qwcfz4MPzBUxjSevweNFQx7SAYZATtcDw\", \"xpub\": \"ypub6WWc2gWwHbdnAAyJDnR4SPL1phRh7REqrPBfZeizaQ1EmTshieRXJC3Z5YoU4wkcdKHEjQGkh6AYEzCQC1Kz3DNaWSwdc1pc8416hAjzqyD\", \"label\": \"Coldcard Import 0x60d1af8b\", \"ckcc_xfp\": 1624354699, \"type\": \"hardware\", \"hw_type\": \"coldcard\", \"derivation\": \"m/49'/0'/0'\"}, \"wallet_type\": \"standard\", \"use_encryption\": false, \"seed_version\": 17}";
                response = await controller.UpdateWallet(new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode, WalletFile = TestUtils.GetFormFile("coldcard-ypub.json", content) });

                setupVm = (WalletSetupViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.False(setupVm.Confirmation); // Should fail, we are giving a mainnet file to a testnet network

                // And with a good file? (upub)
                content  = "{\"keystore\": {\"ckcc_xpub\": \"tpubD6NzVbkrYhZ4YHNiuTdTmHRmbcPRLfqgyneZFCL1mkzkUBjXriQShxTh9HL34FK2mhieasJVk9EzJrUfkFqRNQBjiXgx3n5BhPkxKBoFmaS\", \"xpub\": \"upub5DBYp1qGgsTrkzCptMGZc2x18pquLwGrBw6nS59T4NViZ4cni1mGowQzziy85K8vzkp1jVtWrSkLhqk9KDfvrGeB369wGNYf39kX8rQfiLn\", \"label\": \"Coldcard Import 0x60d1af8b\", \"ckcc_xfp\": 1624354699, \"type\": \"hardware\", \"hw_type\": \"coldcard\", \"derivation\": \"m/49'/0'/0'\"}, \"wallet_type\": \"standard\", \"use_encryption\": false, \"seed_version\": 17}";
                response = await controller.UpdateWallet(new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode, WalletFile = TestUtils.GetFormFile("coldcard-upub.json", content) });

                setupVm = (WalletSetupViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.True(setupVm.Confirmation);
                response = await controller.UpdateWallet(setupVm);

                Assert.IsType <RedirectToActionResult>(response);
                response = await controller.WalletSettings(storeId, cryptoCode);

                settingsVm = (WalletSettingsViewModel)Assert.IsType <ViewResult>(response).Model;
                Assert.Equal("ElectrumFile", settingsVm.Source);

                // Now let's check that no data has been lost in the process
                var store      = tester.PayTester.StoreRepository.FindStore(storeId).GetAwaiter().GetResult();
                var onchainBTC = store.GetSupportedPaymentMethods(tester.PayTester.Networks)
#pragma warning disable CS0618 // Type or member is obsolete
                                 .OfType <DerivationSchemeSettings>().First(o => o.PaymentId.IsBTCOnChain);
#pragma warning restore CS0618 // Type or member is obsolete
                DerivationSchemeSettings.TryParseFromWalletFile(content, onchainBTC.Network, out var expected);
                Assert.Equal(expected.ToJson(), onchainBTC.ToJson());

                // Let's check that the root hdkey and account key path are taken into account when making a PSBT
                invoice = await user.BitPay.CreateInvoiceAsync(
                    new Invoice
                {
                    Price             = 1.5m,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some description",
                    FullNotifications = true
                }, Facade.Merchant);

                tester.ExplorerNode.Generate(1);
                var invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo.First(c => c.CryptoCode == cryptoCode).Address,
                                                           tester.ExplorerNode.Network);
                tester.ExplorerNode.SendToAddress(invoiceAddress, Money.Coins(1m));
                TestUtils.Eventually(() =>
                {
                    invoice = user.BitPay.GetInvoice(invoice.Id);
                    Assert.Equal("paid", invoice.Status);
                });
                var wallet = tester.PayTester.GetController <UIWalletsController>();
                var psbt   = wallet.CreatePSBT(btcNetwork, onchainBTC,
                                               new WalletSendModel()
                {
                    Outputs = new List <WalletSendModel.TransactionOutput>
                    {
                        new WalletSendModel.TransactionOutput
                        {
                            Amount             = 0.5m,
                            DestinationAddress = new Key().PubKey.GetAddress(ScriptPubKeyType.Legacy, btcNetwork.NBitcoinNetwork)
                                                 .ToString(),
                        }
                    },
                    FeeSatoshiPerByte = 1
                }, default).GetAwaiter().GetResult();

                Assert.NotNull(psbt);

                var root = new Mnemonic(
                    "usage fever hen zero slide mammal silent heavy donate budget pulse say brain thank sausage brand craft about save attract muffin advance illegal cabbage")
                           .DeriveExtKey().AsHDKeyCache();
                var account = root.Derive(new KeyPath("m/49'/0'/0'"));
                Assert.All(psbt.PSBT.Inputs, input =>
                {
                    var keyPath = input.HDKeyPaths.Single();
                    Assert.False(keyPath.Value.KeyPath.IsHardened);
                    Assert.Equal(account.Derive(keyPath.Value.KeyPath).GetPublicKey(), keyPath.Key);
                    Assert.Equal(keyPath.Value.MasterFingerprint,
                                 onchainBTC.AccountKeySettings[0].AccountKey.GetPublicKey().GetHDFingerPrint());
                });
            }
        }
Пример #7
0
        public async Task CanHaveLTCOnlyStore()
        {
            using (var tester = CreateServerTester())
            {
                tester.ActivateLTC();
                await tester.StartAsync();

                var user = tester.NewAccount();
                user.GrantAccess();
                user.RegisterDerivationScheme("LTC");

                // First we try payment with a merchant having only BTC
                var invoice = user.BitPay.CreateInvoice(
                    new Invoice()
                {
                    Price             = 500,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some description",
                    FullNotifications = true
                }, Facade.Merchant);

                Assert.Single(invoice.CryptoInfo);
                Assert.Equal("LTC", invoice.CryptoInfo[0].CryptoCode);
                Assert.True(invoice.PaymentCodes.ContainsKey("LTC"));
                Assert.True(invoice.SupportedTransactionCurrencies.ContainsKey("LTC"));
                Assert.True(invoice.SupportedTransactionCurrencies["LTC"].Enabled);
                Assert.True(invoice.PaymentSubtotals.ContainsKey("LTC"));
                Assert.True(invoice.PaymentTotals.ContainsKey("LTC"));
                var cashCow        = tester.LTCExplorerNode;
                var invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo[0].Address, cashCow.Network);
                var firstPayment   = Money.Coins(0.1m);
                cashCow.SendToAddress(invoiceAddress, firstPayment);
                TestUtils.Eventually(() =>
                {
                    invoice = user.BitPay.GetInvoice(invoice.Id);
                    Assert.Equal(firstPayment, invoice.CryptoInfo[0].Paid);
                });

                Assert.Single(invoice.CryptoInfo); // Only BTC should be presented

                var controller = tester.PayTester.GetController <UIInvoiceController>(null);
                var checkout   =
                    (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id)
                                                          .GetAwaiter().GetResult()).Value;
                Assert.Single(checkout.AvailableCryptos);
                Assert.Equal("LTC", checkout.CryptoCode);

                //////////////////////

                // Despite it is called BitcoinAddress it should be LTC because BTC is not available
                Assert.Null(invoice.BitcoinAddress);
                Assert.NotEqual(1.0m, invoice.Rate);
                Assert.NotEqual(invoice.BtcDue, invoice.CryptoInfo[0].Due); // Should be BTC rate
                cashCow.SendToAddress(invoiceAddress, invoice.CryptoInfo[0].Due);

                TestUtils.Eventually(() =>
                {
                    invoice = user.BitPay.GetInvoice(invoice.Id);
                    Assert.Equal("paid", invoice.Status);
                    checkout = (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id)
                                                                     .GetAwaiter().GetResult()).Value;
                    Assert.Equal("paid", checkout.Status);
                });
            }
        }
Пример #8
0
        public async Task CanPlayWithPSBT()
        {
            using (var tester = ServerTester.Create())
            {
                tester.Start();
                var user = tester.NewAccount();
                user.GrantAccess();
                user.RegisterDerivationScheme("BTC");
                var invoice = user.BitPay.CreateInvoice(new Invoice()
                {
                    Price             = 10,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some \", description",
                    FullNotifications = true
                }, Facade.Merchant);
                var cashCow        = tester.ExplorerNode;
                var invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo[0].Address, cashCow.Network);
                cashCow.SendToAddress(invoiceAddress, Money.Coins(1.5m));
                TestUtils.Eventually(() =>
                {
                    invoice = user.BitPay.GetInvoice(invoice.Id);
                    Assert.Equal("paid", invoice.Status);
                });

                var walletController = tester.PayTester.GetController <WalletsController>(user.UserId);
                var walletId         = new WalletId(user.StoreId, "BTC");
                var sendDestination  = new Key().PubKey.Hash.GetAddress(user.SupportedNetwork.NBitcoinNetwork).ToString();
                var sendModel        = new WalletSendModel()
                {
                    Destination       = sendDestination,
                    Amount            = 0.1m,
                    FeeSatoshiPerByte = 1,
                    CurrentBalance    = 1.5m
                };
                var vmLedger = await walletController.WalletSend(walletId, sendModel, command : "ledger").AssertViewModelAsync <WalletSendLedgerModel>();

                PSBT.Parse(vmLedger.PSBT, user.SupportedNetwork.NBitcoinNetwork);
                BitcoinAddress.Create(vmLedger.HintChange, user.SupportedNetwork.NBitcoinNetwork);
                Assert.NotNull(vmLedger.SuccessPath);
                Assert.NotNull(vmLedger.WebsocketPath);

                var redirectedPSBT = (string)Assert.IsType <RedirectToActionResult>(await walletController.WalletSend(walletId, sendModel, command: "analyze-psbt")).RouteValues["psbt"];
                var vmPSBT         = walletController.WalletPSBT(walletId, new WalletPSBTViewModel()
                {
                    PSBT = redirectedPSBT
                }).AssertViewModel <WalletPSBTViewModel>();
                var unsignedPSBT = PSBT.Parse(vmPSBT.PSBT, user.SupportedNetwork.NBitcoinNetwork);
                Assert.NotNull(vmPSBT.Decoded);

                var filePSBT = (FileContentResult)(await walletController.WalletPSBT(walletId, vmPSBT, "save-psbt"));
                PSBT.Load(filePSBT.FileContents, user.SupportedNetwork.NBitcoinNetwork);

                await walletController.WalletPSBT(walletId, vmPSBT, "ledger").AssertViewModelAsync <WalletSendLedgerModel>();

                var vmPSBT2 = await walletController.WalletPSBT(walletId, vmPSBT, "broadcast").AssertViewModelAsync <WalletPSBTViewModel>();

                Assert.NotEmpty(vmPSBT2.Errors);
                Assert.Equal(vmPSBT.Decoded, vmPSBT2.Decoded);
                Assert.Equal(vmPSBT.PSBT, vmPSBT2.PSBT);

                var signedPSBT = unsignedPSBT.Clone();
                signedPSBT.SignAll(user.ExtKey);
                vmPSBT.PSBT = signedPSBT.ToBase64();
                var psbtReady = await walletController.WalletPSBT(walletId, vmPSBT, "broadcast").AssertViewModelAsync <WalletPSBTReadyViewModel>();

                Assert.Equal(2, psbtReady.Destinations.Count);
                Assert.Contains(psbtReady.Destinations, d => d.Destination == sendDestination && !d.Positive);
                Assert.Contains(psbtReady.Destinations, d => d.Positive);
                var redirect = Assert.IsType <RedirectToActionResult>(await walletController.WalletPSBTReady(walletId, psbtReady, command: "broadcast"));
                Assert.Equal(nameof(walletController.WalletTransactions), redirect.ActionName);

                vmPSBT.PSBT = unsignedPSBT.ToBase64();
                var combineVM = await walletController.WalletPSBT(walletId, vmPSBT, "combine").AssertViewModelAsync <WalletPSBTCombineViewModel>();

                Assert.Equal(vmPSBT.PSBT, combineVM.OtherPSBT);
                combineVM.PSBT = signedPSBT.ToBase64();
                vmPSBT         = await walletController.WalletPSBTCombine(walletId, combineVM).AssertViewModelAsync <WalletPSBTViewModel>();

                var signedPSBT2 = PSBT.Parse(vmPSBT.PSBT, user.SupportedNetwork.NBitcoinNetwork);
                Assert.True(signedPSBT.TryFinalize(out _));
                Assert.True(signedPSBT2.TryFinalize(out _));
                Assert.Equal(signedPSBT, signedPSBT2);

                // Can use uploaded file?
                combineVM.PSBT             = null;
                combineVM.UploadedPSBTFile = TestUtils.GetFormFile("signedPSBT", signedPSBT.ToBytes());
                vmPSBT = await walletController.WalletPSBTCombine(walletId, combineVM).AssertViewModelAsync <WalletPSBTViewModel>();

                signedPSBT2 = PSBT.Parse(vmPSBT.PSBT, user.SupportedNetwork.NBitcoinNetwork);
                Assert.True(signedPSBT.TryFinalize(out _));
                Assert.True(signedPSBT2.TryFinalize(out _));
                Assert.Equal(signedPSBT, signedPSBT2);

                var ready = (await walletController.WalletPSBTReady(walletId, signedPSBT.ToBase64())).AssertViewModel <WalletPSBTReadyViewModel>();
                Assert.Equal(signedPSBT.ToBase64(), ready.PSBT);
                redirect = Assert.IsType <RedirectToActionResult>(await walletController.WalletPSBTReady(walletId, ready, command: "analyze-psbt"));
                Assert.Equal(signedPSBT.ToBase64(), (string)redirect.RouteValues["psbt"]);
                redirect = Assert.IsType <RedirectToActionResult>(await walletController.WalletPSBTReady(walletId, ready, command: "broadcast"));
                Assert.Equal(nameof(walletController.WalletTransactions), redirect.ActionName);
            }
        }
Пример #9
0
        public void CanComputeCrowdfundModel()
        {
            using (var tester = ServerTester.Create())
            {
                tester.Start();
                var user = tester.NewAccount();
                user.GrantAccess();
                user.RegisterDerivationScheme("BTC");
                user.ModifyStore(s => s.NetworkFeeMode = NetworkFeeMode.Never);
                var apps = user.GetController <AppsController>();
                var vm   = Assert.IsType <CreateAppViewModel>(Assert.IsType <ViewResult>(apps.CreateApp().Result).Model);
                vm.Name            = "test";
                vm.SelectedAppType = AppType.Crowdfund.ToString();
                Assert.IsType <RedirectToActionResult>(apps.CreateApp(vm).Result);
                var appId = Assert.IsType <ListAppsViewModel>(Assert.IsType <ViewResult>(apps.ListApps().Result).Model)
                            .Apps[0].Id;

                Logs.Tester.LogInformation("We create an invoice with a hardcap");
                var crowdfundViewModel = Assert.IsType <UpdateCrowdfundViewModel>(Assert
                                                                                  .IsType <ViewResult>(apps.UpdateCrowdfund(appId).Result).Model);
                crowdfundViewModel.Enabled             = true;
                crowdfundViewModel.EndDate             = null;
                crowdfundViewModel.TargetAmount        = 100;
                crowdfundViewModel.TargetCurrency      = "BTC";
                crowdfundViewModel.UseAllStoreInvoices = true;
                crowdfundViewModel.EnforceTargetAmount = true;
                Assert.IsType <RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);

                var anonAppPubsController = tester.PayTester.GetController <AppsPublicController>();
                var publicApps            = user.GetController <AppsPublicController>();

                var model = Assert.IsType <ViewCrowdfundViewModel>(Assert
                                                                   .IsType <ViewResult>(publicApps.ViewCrowdfund(appId, String.Empty).Result).Model);


                Assert.Equal(crowdfundViewModel.TargetAmount, model.TargetAmount);
                Assert.Equal(crowdfundViewModel.EndDate, model.EndDate);
                Assert.Equal(crowdfundViewModel.StartDate, model.StartDate);
                Assert.Equal(crowdfundViewModel.TargetCurrency, model.TargetCurrency);
                Assert.Equal(0m, model.Info.CurrentAmount);
                Assert.Equal(0m, model.Info.CurrentPendingAmount);
                Assert.Equal(0m, model.Info.ProgressPercentage);


                Logs.Tester.LogInformation("Unpaid invoices should show as pending contribution because it is hardcap");
                Logs.Tester.LogInformation("Because UseAllStoreInvoices is true, we can manually create an invoice and it should show as contribution");
                var invoice = user.BitPay.CreateInvoice(new Invoice()
                {
                    Buyer = new Buyer()
                    {
                        email = "*****@*****.**"
                    },
                    Price             = 1m,
                    Currency          = "BTC",
                    PosData           = "posData",
                    ItemDesc          = "Some description",
                    TransactionSpeed  = "high",
                    FullNotifications = true
                }, Facade.Merchant);


                model = Assert.IsType <ViewCrowdfundViewModel>(Assert
                                                               .IsType <ViewResult>(publicApps.ViewCrowdfund(appId, String.Empty).Result).Model);

                Assert.Equal(0m, model.Info.CurrentAmount);
                Assert.Equal(1m, model.Info.CurrentPendingAmount);
                Assert.Equal(0m, model.Info.ProgressPercentage);
                Assert.Equal(1m, model.Info.PendingProgressPercentage);

                Logs.Tester.LogInformation("Let's check current amount change once payment is confirmed");
                var invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo[0].Address, tester.ExplorerNode.Network);
                tester.ExplorerNode.SendToAddress(invoiceAddress, invoice.BtcDue);
                tester.ExplorerNode.Generate(1); // By default invoice confirmed at 1 block
                TestUtils.Eventually(() =>
                {
                    model = Assert.IsType <ViewCrowdfundViewModel>(Assert
                                                                   .IsType <ViewResult>(publicApps.ViewCrowdfund(appId, String.Empty).Result).Model);
                    Assert.Equal(1m, model.Info.CurrentAmount);
                    Assert.Equal(0m, model.Info.CurrentPendingAmount);
                });

                Logs.Tester.LogInformation("Because UseAllStoreInvoices is true, let's make sure the invoice is tagged");
                var invoiceEntity = tester.PayTester.InvoiceRepository.GetInvoice(invoice.Id).GetAwaiter().GetResult();
                Assert.True(invoiceEntity.Version >= InvoiceEntity.InternalTagSupport_Version);
                Assert.Contains(AppService.GetAppInternalTag(appId), invoiceEntity.InternalTags);

                crowdfundViewModel.UseAllStoreInvoices = false;
                Assert.IsType <RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);

                Logs.Tester.LogInformation("Because UseAllStoreInvoices is false, let's make sure the invoice is not tagged");
                invoice = user.BitPay.CreateInvoice(new Invoice()
                {
                    Buyer = new Buyer()
                    {
                        email = "*****@*****.**"
                    },
                    Price             = 1m,
                    Currency          = "BTC",
                    PosData           = "posData",
                    ItemDesc          = "Some description",
                    TransactionSpeed  = "high",
                    FullNotifications = true
                }, Facade.Merchant);
                invoiceEntity = tester.PayTester.InvoiceRepository.GetInvoice(invoice.Id).GetAwaiter().GetResult();
                Assert.DoesNotContain(AppService.GetAppInternalTag(appId), invoiceEntity.InternalTags);

                Logs.Tester.LogInformation("After turning setting a softcap, let's check that only actual payments are counted");
                crowdfundViewModel.EnforceTargetAmount = false;
                crowdfundViewModel.UseAllStoreInvoices = true;
                Assert.IsType <RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);
                invoice = user.BitPay.CreateInvoice(new Invoice()
                {
                    Buyer = new Buyer()
                    {
                        email = "*****@*****.**"
                    },
                    Price             = 1m,
                    Currency          = "BTC",
                    PosData           = "posData",
                    ItemDesc          = "Some description",
                    TransactionSpeed  = "high",
                    FullNotifications = true
                }, Facade.Merchant);
                Assert.Equal(0m, model.Info.CurrentPendingAmount);
                invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo[0].Address, tester.ExplorerNode.Network);
                tester.ExplorerNode.SendToAddress(invoiceAddress, Money.Coins(0.5m));
                tester.ExplorerNode.SendToAddress(invoiceAddress, Money.Coins(0.2m));
                TestUtils.Eventually(() =>
                {
                    model = Assert.IsType <ViewCrowdfundViewModel>(Assert
                                                                   .IsType <ViewResult>(publicApps.ViewCrowdfund(appId, String.Empty).Result).Model);
                    Assert.Equal(0.7m, model.Info.CurrentPendingAmount);
                });
            }
        }
Пример #10
0
        public async Task CanUseEthereum()
        {
            using var s = SeleniumTester.Create("ETHEREUM", true);
            s.Server.ActivateETH();
            await s.StartAsync();

            s.RegisterNewUser(true);

            IWebElement syncSummary = null;

            TestUtils.Eventually(() =>
            {
                syncSummary = s.Driver.FindElement(By.Id("modalDialog"));
                Assert.True(syncSummary.Displayed);
            });
            var web3Link = syncSummary.FindElement(By.LinkText("Configure Web3"));

            web3Link.Click();
            s.Driver.FindElement(By.Id("Web3ProviderUrl")).SendKeys("https://ropsten-rpc.linkpool.io");
            s.Driver.FindElement(By.Id("saveButton")).Click();
            s.AssertHappyMessage();
            TestUtils.Eventually(() =>
            {
                s.Driver.Navigate().Refresh();
                s.Driver.AssertElementNotFound(By.Id("modalDialog"));
            });

            var store = s.CreateNewStore();

            s.Driver.FindElement(By.LinkText("Ethereum")).Click();

            var seed = new Mnemonic(Wordlist.English);

            s.Driver.FindElement(By.Id("ModifyETH")).Click();
            s.Driver.FindElement(By.Id("Seed")).SendKeys(seed.ToString());
            s.SetCheckbox(s.Driver.FindElement(By.Id("StoreSeed")), true);
            s.SetCheckbox(s.Driver.FindElement(By.Id("Enabled")), true);
            s.Driver.FindElement(By.Id("SaveButton")).Click();
            s.AssertHappyMessage();
            s.Driver.FindElement(By.Id("ModifyUSDT20")).Click();
            s.Driver.FindElement(By.Id("Seed")).SendKeys(seed.ToString());
            s.SetCheckbox(s.Driver.FindElement(By.Id("StoreSeed")), true);
            s.SetCheckbox(s.Driver.FindElement(By.Id("Enabled")), true);
            s.Driver.FindElement(By.Id("SaveButton")).Click();
            s.AssertHappyMessage();

            var invoiceId = s.CreateInvoice(store.storeName, 10);

            s.GoToInvoiceCheckout(invoiceId);
            var currencyDropdownButton = s.Driver.WaitForElement(By.ClassName("payment__currencies"));

            Assert.Contains("ETH", currencyDropdownButton.Text);
            s.Driver.FindElement(By.Id("copy-tab")).Click();

            var ethAddress = s.Driver.FindElements(By.ClassName("copySectionBox"))
                             .Single(element => element.FindElement(By.TagName("label")).Text
                                     .Contains("Address", StringComparison.InvariantCultureIgnoreCase)).FindElement(By.TagName("input"))
                             .GetAttribute("value");

            currencyDropdownButton.Click();
            var elements = s.Driver.FindElement(By.ClassName("vex-content")).FindElements(By.ClassName("vexmenuitem"));

            Assert.Equal(2, elements.Count);

            elements.Single(element => element.Text.Contains("USDT20")).Click();
            s.Driver.FindElement(By.Id("copy-tab")).Click();
            var usdtAddress = s.Driver.FindElements(By.ClassName("copySectionBox"))
                              .Single(element => element.FindElement(By.TagName("label")).Text
                                      .Contains("Address", StringComparison.InvariantCultureIgnoreCase)).FindElement(By.TagName("input"))
                              .GetAttribute("value");

            Assert.Equal(usdtAddress, ethAddress);
        }
Пример #11
0
        public async Task CanPlayWithPSBT()
        {
            using (var tester = ServerTester.Create())
            {
                await tester.StartAsync();

                var user = tester.NewAccount();
                user.GrantAccess();
                user.RegisterDerivationScheme("BTC");
                var invoice = user.BitPay.CreateInvoice(new Invoice()
                {
                    Price             = 10,
                    Currency          = "USD",
                    PosData           = "posData",
                    OrderId           = "orderId",
                    ItemDesc          = "Some \", description",
                    FullNotifications = true
                }, Facade.Merchant);
                var cashCow        = tester.ExplorerNode;
                var invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo[0].Address, cashCow.Network);
                cashCow.SendToAddress(invoiceAddress, Money.Coins(1.5m));
                TestUtils.Eventually(() =>
                {
                    invoice = user.BitPay.GetInvoice(invoice.Id);
                    Assert.Equal("paid", invoice.Status);
                });

                var walletController = user.GetController <WalletsController>();
                var walletId         = new WalletId(user.StoreId, "BTC");
                var sendDestination  = new Key().PubKey.Hash.GetAddress(user.SupportedNetwork.NBitcoinNetwork).ToString();
                var sendModel        = new WalletSendModel()
                {
                    Outputs = new List <WalletSendModel.TransactionOutput>()
                    {
                        new WalletSendModel.TransactionOutput()
                        {
                            DestinationAddress = sendDestination,
                            Amount             = 0.1m,
                        }
                    },
                    FeeSatoshiPerByte = 1,
                    CurrentBalance    = 1.5m
                };

                string redirectedPSBT = AssertRedirectedPSBT(await walletController.WalletSend(walletId, sendModel, command: "analyze-psbt"), nameof(walletController.WalletPSBT));
                var    vmPSBT         = await walletController.WalletPSBT(walletId, new WalletPSBTViewModel()
                {
                    PSBT = redirectedPSBT
                }).AssertViewModelAsync <WalletPSBTViewModel>();

                var unsignedPSBT = PSBT.Parse(vmPSBT.PSBT, user.SupportedNetwork.NBitcoinNetwork);
                Assert.NotNull(vmPSBT.Decoded);

                var filePSBT = (FileContentResult)(await walletController.WalletPSBT(walletId, vmPSBT, "save-psbt"));
                PSBT.Load(filePSBT.FileContents, user.SupportedNetwork.NBitcoinNetwork);

                var vmPSBT2 = await walletController.WalletPSBTReady(walletId, new WalletPSBTReadyViewModel()
                {
                    SigningContext = new SigningContextModel()
                    {
                        PSBT = AssertRedirectedPSBT(await walletController.WalletPSBT(walletId, vmPSBT, "broadcast"), nameof(walletController.WalletPSBTReady))
                    }
                }).AssertViewModelAsync <WalletPSBTReadyViewModel>();

                Assert.NotEmpty(vmPSBT2.Inputs.Where(i => i.Error != null));
                Assert.Equal(vmPSBT.PSBT, vmPSBT2.SigningContext.PSBT);

                var signedPSBT = unsignedPSBT.Clone();
                signedPSBT.SignAll(user.DerivationScheme, user.GenerateWalletResponseV.AccountHDKey, user.GenerateWalletResponseV.AccountKeyPath);
                vmPSBT.PSBT = signedPSBT.ToBase64();
                var psbtReady = await walletController.WalletPSBTReady(walletId, new WalletPSBTReadyViewModel
                {
                    SigningContext = new SigningContextModel
                    {
                        PSBT = AssertRedirectedPSBT(await walletController.WalletPSBT(walletId, vmPSBT, "broadcast"), nameof(walletController.WalletPSBTReady))
                    }
                }).AssertViewModelAsync <WalletPSBTReadyViewModel>();

                Assert.Equal(2 + 1, psbtReady.Destinations.Count); // The fee is a destination
                Assert.Contains(psbtReady.Destinations, d => d.Destination == sendDestination && !d.Positive);
                Assert.Contains(psbtReady.Destinations, d => d.Positive);

                vmPSBT.PSBT = unsignedPSBT.ToBase64();
                var combineVM = await walletController.WalletPSBT(walletId, vmPSBT, "combine").AssertViewModelAsync <WalletPSBTCombineViewModel>();

                Assert.Equal(vmPSBT.PSBT, combineVM.OtherPSBT);
                combineVM.PSBT = signedPSBT.ToBase64();
                var psbt = AssertRedirectedPSBT(await walletController.WalletPSBTCombine(walletId, combineVM), nameof(walletController.WalletPSBT));

                var signedPSBT2 = PSBT.Parse(psbt, user.SupportedNetwork.NBitcoinNetwork);
                Assert.True(signedPSBT.TryFinalize(out _));
                Assert.True(signedPSBT2.TryFinalize(out _));
                Assert.Equal(signedPSBT, signedPSBT2);

                // Can use uploaded file?
                combineVM.PSBT             = null;
                combineVM.UploadedPSBTFile = TestUtils.GetFormFile("signedPSBT", signedPSBT.ToBytes());
                psbt        = AssertRedirectedPSBT(await walletController.WalletPSBTCombine(walletId, combineVM), nameof(walletController.WalletPSBT));
                signedPSBT2 = PSBT.Parse(psbt, user.SupportedNetwork.NBitcoinNetwork);
                Assert.True(signedPSBT.TryFinalize(out _));
                Assert.True(signedPSBT2.TryFinalize(out _));
                Assert.Equal(signedPSBT, signedPSBT2);

                var ready = (await walletController.WalletPSBTReady(walletId, new WalletPSBTReadyViewModel
                {
                    SigningContext = new SigningContextModel(signedPSBT)
                })).AssertViewModel <WalletPSBTReadyViewModel>();
                Assert.Equal(signedPSBT.ToBase64(), ready.SigningContext.PSBT);
                psbt = AssertRedirectedPSBT(await walletController.WalletPSBTReady(walletId, ready, command: "analyze-psbt"), nameof(walletController.WalletPSBT));
                Assert.Equal(signedPSBT.ToBase64(), psbt);
                var redirect = Assert.IsType <RedirectToActionResult>(await walletController.WalletPSBTReady(walletId, ready, command: "broadcast"));
                Assert.Equal(nameof(walletController.WalletTransactions), redirect.ActionName);

                //test base64 psbt file
                Assert.False(string.IsNullOrEmpty(Assert.IsType <WalletPSBTViewModel>(
                                                      Assert.IsType <ViewResult>(
                                                          await walletController.WalletPSBT(walletId,
                                                                                            new WalletPSBTViewModel()
                {
                    UploadedPSBTFile = TestUtils.GetFormFile("base64", signedPSBT.ToBase64())
                })).Model).PSBT));
            }
        }