Files
pay/main.cpp
T

222 lines
7.6 KiB
C++
Raw Permalink Normal View History

2020-10-17 16:40:48 +02:00
/*
* This file is part of the Flowee project
2021-05-07 19:47:11 +02:00
* Copyright (C) 2020-2021 Tom Zander <tom@flowee.org>
2020-10-17 16:40:48 +02:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "BitcoinValue.h"
#include "FloweePay.h"
2020-05-24 13:20:03 +02:00
#include "NetDataProvider.h"
2021-10-25 19:42:13 +02:00
#include "NewWalletConfig.h"
2020-05-24 13:20:03 +02:00
#include "PortfolioDataProvider.h"
2021-05-07 19:47:11 +02:00
#include "PriceDataProvider.h"
2021-11-16 11:47:33 +01:00
#include "Payment.h"
#include "QRCreator.h"
2020-05-24 13:20:03 +02:00
2020-10-14 15:12:33 +02:00
#include <primitives/key.h> // for ECC_Start()
2020-05-24 13:20:03 +02:00
#include <QCommandLineParser>
#include <QDateTime>
2021-06-24 18:53:52 +02:00
#include <QFileInfo>
2020-05-24 13:20:03 +02:00
#include <QGuiApplication>
2020-12-26 15:30:52 +01:00
#include <QIcon>
2020-05-24 13:20:03 +02:00
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStandardPaths>
2021-01-28 21:03:52 +01:00
#include <QTranslator>
2020-05-24 13:20:03 +02:00
2020-08-11 22:42:32 +02:00
#include <signal.h>
2020-05-24 13:20:03 +02:00
namespace {
void HandleSigTerm(int) {
QCoreApplication::quit();
}
struct ECC_State
{
ECC_State() {
// Init crypto lib.
ECC_Start();
}
~ECC_State() {
ECC_Stop();
}
};
}
// defined in qml_path_helper.cpp.in
void handleLocalQml(QQmlApplicationEngine &engine);
2020-05-24 13:20:03 +02:00
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication qapp(argc, argv);
qapp.setOrganizationName("flowee");
qapp.setApplicationName("pay");
2021-11-29 23:18:53 +01:00
qapp.setApplicationVersion("2021.07.0");
2020-12-26 15:30:52 +01:00
qapp.setWindowIcon(QIcon(":/FloweePay.png"));
2020-05-24 13:20:03 +02:00
srand((quint32) QDateTime::currentMSecsSinceEpoch());
2021-11-02 19:29:14 +01:00
qmlRegisterType<FloweePay>("Flowee.org.pay", 1, 0, "Bitcoin");
2020-06-12 20:53:01 +02:00
qmlRegisterType<BitcoinValue>("Flowee.org.pay", 1, 0, "BitcoinValue");
2021-10-25 19:42:13 +02:00
qmlRegisterType<NewWalletConfig>("Flowee.org.pay", 1, 0, "NewWalletConfig");
2021-11-16 11:47:33 +01:00
qmlRegisterType<Payment>("Flowee.org.pay", 1, 0, "Payment");
2020-05-24 13:20:03 +02:00
QCommandLineParser parser;
parser.setApplicationDescription("Flowee pay");
QCommandLineOption debug(QStringList() << "debug", "Use debug level logging");
QCommandLineOption verbose(QStringList() << "verbose" << "v", "Be more verbose");
QCommandLineOption quiet(QStringList() << "quiet" << "q", "Be quiet, only errors are shown");
QCommandLineOption connect(QStringList() << "connect", "Connect to HOST", "HOST");
2020-10-29 21:51:52 +01:00
QCommandLineOption testnet4(QStringList() << "testnet4", "Use testnet4");
2020-05-24 13:20:03 +02:00
parser.addHelpOption();
parser.addOption(debug);
parser.addOption(verbose);
parser.addOption(quiet);
parser.addOption(connect);
2020-10-29 21:51:52 +01:00
parser.addOption(testnet4);
// nice features to test your QML changes.
2021-11-20 22:24:19 +01:00
QCommandLineOption offline(QStringList() << "offline", "Do not connect");
parser.addOption(offline);
2021-06-24 18:53:52 +02:00
#ifndef NDEBUG
// to protect people from the bad effect of having and later not having headers we only allow this
// override in debug mode.
QCommandLineOption headers(QStringList() << "headers", "Override location of blockheaders", "PATH");
parser.addOption(headers);
#endif
2020-05-24 13:20:03 +02:00
parser.process(qapp);
auto *logger = Log::Manager::instance();
logger->clearChannels();
Log::Verbosity v = Log::WarningLevel;
#ifndef BCH_NO_DEBUG_OUTPUT
if (parser.isSet(debug))
v = Log::DebugLevel;
else
#endif
if (parser.isSet(verbose))
v = Log::InfoLevel;
else if (parser.isSet(quiet))
v = Log::FatalLevel;
logger->clearLogLevels(v);
logger->addConsoleChannel();
static const char* languagePacks[] = {
"floweepay-desktop",
"floweepay-common",
"floweepay-mobile",
nullptr
};
for (int i = 0; languagePacks[i]; ++i) {
auto *translator = new QTranslator(&qapp);
if (translator->load(QLocale(), languagePacks[i], QLatin1String("_"), QLatin1String(":/i18n")))
QCoreApplication::installTranslator(translator);
else
delete translator;
}
2021-01-28 21:03:52 +01:00
2021-05-07 19:47:11 +02:00
PriceDataProvider prices;
2020-10-29 21:51:52 +01:00
// select chain
2021-06-24 18:53:52 +02:00
auto chain = P2PNet::MainChain;
2020-10-29 21:51:52 +01:00
if (parser.isSet(testnet4))
2021-06-24 18:53:52 +02:00
chain = P2PNet::Testnet4Chain;
2021-11-23 17:16:45 +01:00
if (parser.isSet(offline))
prices.mock(50000);
else if (!parser.isSet(testnet4))
2021-05-07 19:47:11 +02:00
prices.start();
2021-06-24 18:53:52 +02:00
FloweePay::selectChain(chain);
std::unique_ptr<QFile> blockheaders; // pointer to own the memmapped blockheaders file.
// lets try by default to open the path /usr/share/floweepay/*
blockheaders.reset(new QFile(QString("/usr/share/floweepay/")
+ (chain == P2PNet::MainChain ? "blockheaders" : "blockheaders-testnet4")));
#ifndef NDEBUG
// override only available in debug mode
if (parser.isSet(headers)) {
QFileInfo info(parser.value(headers));
if (info.exists()) {
if (info.isDir())
blockheaders.reset(new QFile(info.absoluteFilePath()
+ (chain == P2PNet::MainChain ? "/blockheaders" : "/blockheaders-testnet4")));
else
blockheaders.reset(new QFile(info.absoluteFilePath()));
}
else {
// do not load if pointing to invalid path.
logWarning() << "Headers disabled by cli option";
blockheaders.reset();
}
}
#endif
2021-11-20 22:24:19 +01:00
2021-06-24 18:53:52 +02:00
if (blockheaders) {
if (!blockheaders->open(QIODevice::ReadOnly)) { // can't be opened for reading.
blockheaders.reset();
}
else {
Blockchain::setStaticChain(blockheaders->map(0, blockheaders->size()), blockheaders->size());
blockheaders->close();
}
}
2020-10-29 21:51:52 +01:00
2020-05-24 13:20:03 +02:00
ECC_State crypo_state; // allows the secp256k1 to function.
2021-01-07 20:10:09 +01:00
qmlRegisterType<TransactionInfo>("Flowee.org.pay", 1, 0, "TransactionInfo");
qmlRegisterType<PaymentRequest>("Flowee.org.pay", 1, 0, "PaymentRequest");
2020-05-24 13:20:03 +02:00
QQmlApplicationEngine engine;
engine.addImageProvider(QLatin1String("qr"), new QRCreator());
2021-11-02 19:29:14 +01:00
engine.rootContext()->setContextProperty("Pay", FloweePay::instance());
2021-05-07 19:47:11 +02:00
engine.rootContext()->setContextProperty("Fiat", &prices);
handleLocalQml(engine);
engine.load(engine.baseUrl().url() + "/main.qml");
2020-05-24 13:20:03 +02:00
2021-11-20 22:24:19 +01:00
QObject::connect(FloweePay::instance(), &FloweePay::loadComplete, &engine, [&engine, &parser, &connect, offline]() {
2020-05-24 13:20:03 +02:00
FloweePay *app = FloweePay::instance();
NetDataProvider *netData = new NetDataProvider(app->p2pNet()->blockHeight(), &engine);
app->p2pNet()->addP2PNetListener(netData);
2021-07-30 10:52:09 +02:00
netData->startRefreshTimer();
2020-05-24 13:20:03 +02:00
2020-10-16 18:17:56 +02:00
PortfolioDataProvider *portfolio = new PortfolioDataProvider(&engine);
2020-12-25 23:27:14 +01:00
for (auto &wallet : app->wallets()) {
2020-10-16 18:17:56 +02:00
portfolio->addWalletAccount(wallet);
2020-05-24 13:20:03 +02:00
}
2020-10-16 18:17:56 +02:00
portfolio->selectDefaultWallet();
2020-05-24 13:20:03 +02:00
engine.rootContext()->setContextProperty("net", netData);
2020-10-16 18:17:56 +02:00
engine.rootContext()->setContextProperty("portfolio", portfolio);
2020-05-24 13:20:03 +02:00
if (parser.isSet(connect)) {
app->p2pNet()->connectionManager().peerAddressDb().addOne( // actually connect to it too.
EndPoint(parser.value(connect).toStdString(), 8333));
}
2021-11-20 22:24:19 +01:00
if (!parser.isSet(offline))
2021-11-08 15:36:30 +01:00
app->p2pNet()->start(); // lets go!
2020-05-24 13:20:03 +02:00
});
2020-11-17 22:10:57 +01:00
// Clean shutdown on SIGTERM
2020-05-24 13:20:03 +02:00
struct sigaction sa;
sa.sa_handler = HandleSigTerm;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, nullptr);
sigaction(SIGINT, &sa, nullptr);
2020-11-17 22:10:57 +01:00
// Ignore SIGPIPE
signal(SIGPIPE, SIG_IGN);
2020-05-24 13:20:03 +02:00
return qapp.exec();
}