2020-10-07 10:36:04 +00:00
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
2024-01-01 17:07:58 +00:00
|
|
|
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2024-10-01 20:17:54 +00:00
|
|
|
#include <QSslSocket>
|
|
|
|
|
2024-10-01 02:21:42 +00:00
|
|
|
#include "Application.h"
|
2020-10-07 10:36:04 +00:00
|
|
|
#include "config-feather.h"
|
2021-05-18 15:59:18 +00:00
|
|
|
#include "constants.h"
|
2022-03-04 16:20:17 +00:00
|
|
|
#include "utils/EventFilter.h"
|
2023-02-11 17:11:21 +00:00
|
|
|
#include "utils/os/Prestium.h"
|
2021-05-18 15:59:18 +00:00
|
|
|
#include "WindowManager.h"
|
2023-01-26 12:12:33 +00:00
|
|
|
#include "config.h"
|
2024-10-01 20:17:54 +00:00
|
|
|
#include <wallet/api/wallet2_api.h>
|
|
|
|
#include "libwalletqt/Wallet.h"
|
|
|
|
#include "libwalletqt/WalletManager.h"
|
2023-01-26 12:12:33 +00:00
|
|
|
|
|
|
|
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
|
|
|
|
#define BOOST_STACKTRACE_LINK
|
|
|
|
#include <signal.h>
|
|
|
|
#include <boost/stacktrace.hpp>
|
|
|
|
#include <fstream>
|
|
|
|
#endif
|
|
|
|
|
2020-12-08 16:02:11 +00:00
|
|
|
#if defined(Q_OS_WIN)
|
|
|
|
#include <windows.h>
|
2021-06-25 14:14:49 +00:00
|
|
|
#include <vfw.h>
|
2020-12-08 16:02:11 +00:00
|
|
|
#endif
|
|
|
|
|
2020-10-09 00:37:05 +00:00
|
|
|
#if defined(Q_OS_LINUX) && defined(STATIC)
|
2020-10-07 10:36:04 +00:00
|
|
|
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
|
2023-03-07 22:09:16 +00:00
|
|
|
Q_IMPORT_PLUGIN(QComposePlatformInputContextPlugin) // Needed for dead keys on Linux
|
2024-11-03 16:42:34 +00:00
|
|
|
Q_IMPORT_PLUGIN(QWaylandIntegrationPlugin)
|
|
|
|
Q_IMPORT_PLUGIN(QWaylandXdgShellIntegrationPlugin)
|
|
|
|
Q_IMPORT_PLUGIN(QWaylandBradientDecorationPlugin)
|
2020-10-07 10:36:04 +00:00
|
|
|
#endif
|
|
|
|
|
2024-01-02 20:21:34 +00:00
|
|
|
#if defined(Q_OS_MAC) && defined(STATIC)
|
|
|
|
Q_IMPORT_PLUGIN(QDarwinCameraPermissionPlugin)
|
|
|
|
#endif
|
|
|
|
|
2023-01-26 12:12:33 +00:00
|
|
|
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
|
|
|
|
void signal_handler(int signum) {
|
|
|
|
::signal(signum, SIG_DFL);
|
|
|
|
std::stringstream keyStream;
|
|
|
|
keyStream << boost::stacktrace::stacktrace();
|
|
|
|
std::cout << keyStream.str();
|
|
|
|
|
|
|
|
// Write stack trace to disk
|
2023-09-12 14:15:40 +00:00
|
|
|
if (conf()->get(Config::writeStackTraceToDisk).toBool()) {
|
2023-02-11 17:11:21 +00:00
|
|
|
QString crashLogPath{Config::defaultConfigDir().path() + "/crash_report.txt"};
|
|
|
|
std::ofstream out(crashLogPath.toStdString());
|
2023-02-28 11:32:02 +00:00
|
|
|
out << QString("Version: %1-%2\n").arg(FEATHER_VERSION, FEATHER_COMMIT).toStdString();
|
|
|
|
out << QString("OS: %1\n").arg(QSysInfo::prettyProductName()).toStdString();
|
2023-02-11 17:11:21 +00:00
|
|
|
out << keyStream.str();
|
|
|
|
out.close();
|
|
|
|
}
|
2023-01-26 12:12:33 +00:00
|
|
|
|
|
|
|
::raise(SIGABRT);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-10-07 10:36:04 +00:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
Q_INIT_RESOURCE(assets);
|
|
|
|
|
2023-01-26 12:12:33 +00:00
|
|
|
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
|
|
|
|
::signal(SIGSEGV, &signal_handler);
|
|
|
|
::signal(SIGABRT, &signal_handler);
|
|
|
|
#endif
|
|
|
|
|
2022-02-23 16:04:23 +00:00
|
|
|
#if defined(HAS_TOR_BIN)
|
2020-10-17 21:14:56 +00:00
|
|
|
Q_INIT_RESOURCE(assets_tor);
|
|
|
|
#endif
|
|
|
|
|
2020-12-08 16:02:11 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
|
|
|
freopen("CONOUT$", "w", stdout);
|
|
|
|
freopen("CONOUT$", "w", stderr);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2024-10-01 00:17:51 +00:00
|
|
|
#if defined(Q_OS_LINUX)
|
|
|
|
// PassThrough results in muddy text
|
|
|
|
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
|
|
|
#endif
|
|
|
|
|
2024-10-01 02:21:42 +00:00
|
|
|
Application app(argc, argv);
|
2024-10-01 00:17:51 +00:00
|
|
|
|
2024-10-06 23:48:20 +00:00
|
|
|
QApplication::setApplicationName("FeatherWallet");
|
2024-10-01 00:17:51 +00:00
|
|
|
QApplication::setApplicationVersion(FEATHER_VERSION);
|
2020-10-07 10:36:04 +00:00
|
|
|
|
|
|
|
QCommandLineParser parser;
|
2024-10-01 00:17:51 +00:00
|
|
|
parser.setApplicationDescription("Feather - a free Monero desktop wallet");
|
|
|
|
QCommandLineOption helpOption = parser.addHelpOption();
|
|
|
|
QCommandLineOption versionOption = parser.addVersionOption();
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2024-10-01 00:17:51 +00:00
|
|
|
QCommandLineOption useLocalTorOption("use-local-tor", "Use system wide installed Tor instead of the bundled.");
|
2020-10-07 10:36:04 +00:00
|
|
|
parser.addOption(useLocalTorOption);
|
|
|
|
|
2024-10-01 00:17:51 +00:00
|
|
|
QCommandLineOption quietModeOption("quiet", "Limit console output");
|
2020-10-07 10:36:04 +00:00
|
|
|
parser.addOption(quietModeOption);
|
|
|
|
|
2024-10-01 00:17:51 +00:00
|
|
|
QCommandLineOption stagenetOption("stagenet", "Stagenet is for development purposes only.");
|
2020-10-07 10:36:04 +00:00
|
|
|
parser.addOption(stagenetOption);
|
|
|
|
|
2024-10-01 00:17:51 +00:00
|
|
|
QCommandLineOption testnetOption("testnet", "Testnet is for development purposes only.");
|
2020-10-07 10:36:04 +00:00
|
|
|
parser.addOption(testnetOption);
|
|
|
|
|
2024-10-01 00:17:51 +00:00
|
|
|
parser.process(app);
|
|
|
|
|
|
|
|
if (parser.isSet(versionOption) || parser.isSet(helpOption)) {
|
|
|
|
return EXIT_SUCCESS;
|
2020-10-07 10:36:04 +00:00
|
|
|
}
|
|
|
|
|
2024-10-01 02:21:42 +00:00
|
|
|
if (app.isAlreadyRunning()) {
|
|
|
|
qWarning() << "Another instance of Feather is already running";
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-10-07 10:36:04 +00:00
|
|
|
bool stagenet = parser.isSet(stagenetOption);
|
|
|
|
bool testnet = parser.isSet(testnetOption);
|
|
|
|
bool quiet = parser.isSet(quietModeOption);
|
|
|
|
|
2021-05-18 15:59:18 +00:00
|
|
|
// Setup networkType
|
|
|
|
if (stagenet)
|
|
|
|
constants::networkType = NetworkType::STAGENET;
|
|
|
|
else if (testnet)
|
|
|
|
constants::networkType = NetworkType::TESTNET;
|
|
|
|
else
|
|
|
|
constants::networkType = NetworkType::MAINNET;
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2021-05-18 15:59:18 +00:00
|
|
|
QApplication::setQuitOnLastWindowClosed(false);
|
2024-10-01 00:17:51 +00:00
|
|
|
QApplication::setDesktopSettingsAware(true); // use system font
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2021-05-18 15:59:18 +00:00
|
|
|
// Setup config directories
|
|
|
|
QString configDir = Config::defaultConfigDir().path();
|
2022-02-11 11:50:09 +00:00
|
|
|
QString config_dir_tor = QString("%1/%2").arg(configDir, "tor");
|
|
|
|
QString config_dir_tordata = QString("%1/%2").arg(configDir, "tor/data");
|
2021-05-18 15:59:18 +00:00
|
|
|
QStringList createDirs({configDir, config_dir_tor, config_dir_tordata});
|
|
|
|
for (const auto &d: createDirs) {
|
|
|
|
if (!Utils::dirExists(d)) {
|
|
|
|
qDebug() << QString("Creating directory: %1").arg(d);
|
|
|
|
if (!QDir().mkpath(d)) {
|
|
|
|
qCritical() << "Could not create directory " << d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup logging
|
2021-08-14 14:22:21 +00:00
|
|
|
QString logPath = QString("%1/libwallet.log").arg(configDir);
|
2021-05-18 15:59:18 +00:00
|
|
|
Monero::Utils::onStartup();
|
|
|
|
Monero::Wallet::init("", "feather", logPath.toStdString(), true);
|
|
|
|
|
|
|
|
bool logLevelFromEnv;
|
|
|
|
int logLevel = qEnvironmentVariableIntValue("MONERO_LOG_LEVEL", &logLevelFromEnv);
|
2023-02-11 17:11:21 +00:00
|
|
|
if (logLevelFromEnv) {
|
2023-09-12 14:15:40 +00:00
|
|
|
conf()->set(Config::logLevel, logLevel);
|
2023-02-11 17:11:21 +00:00
|
|
|
} else {
|
2023-09-12 14:15:40 +00:00
|
|
|
logLevel = conf()->get(Config::logLevel).toInt();
|
2022-03-03 15:22:59 +00:00
|
|
|
}
|
2021-05-18 15:59:18 +00:00
|
|
|
|
2023-09-12 14:15:40 +00:00
|
|
|
if (parser.isSet("quiet") || conf()->get(Config::disableLogging).toBool()) {
|
2022-03-03 15:22:59 +00:00
|
|
|
qWarning() << "Logging is disabled";
|
2021-05-18 15:59:18 +00:00
|
|
|
WalletManager::instance()->setLogLevel(-1);
|
2022-03-03 15:22:59 +00:00
|
|
|
}
|
2023-02-11 17:11:21 +00:00
|
|
|
else if (logLevel >= 0 && logLevel <= Monero::WalletManagerFactory::LogLevel_Max) {
|
2021-05-18 15:59:18 +00:00
|
|
|
Monero::WalletManagerFactory::setLogLevel(logLevel);
|
2022-03-03 15:22:59 +00:00
|
|
|
}
|
2021-05-18 15:59:18 +00:00
|
|
|
|
|
|
|
// Setup wallet directory
|
2023-09-12 14:15:40 +00:00
|
|
|
QString walletDir = conf()->get(Config::walletDirectory).toString();
|
2023-01-26 15:05:54 +00:00
|
|
|
if (walletDir.isEmpty() || Utils::isPortableMode()) {
|
2021-05-18 15:59:18 +00:00
|
|
|
walletDir = Utils::defaultWalletDir();
|
2023-09-12 14:15:40 +00:00
|
|
|
conf()->set(Config::walletDirectory, walletDir);
|
2021-05-18 15:59:18 +00:00
|
|
|
}
|
|
|
|
if (!QDir().mkpath(walletDir))
|
|
|
|
qCritical() << "Unable to create dir: " << walletDir;
|
|
|
|
|
2023-02-11 17:11:21 +00:00
|
|
|
// Prestium initial config
|
2023-09-12 14:15:40 +00:00
|
|
|
if (conf()->get(Config::firstRun).toBool() && Prestium::detect()) {
|
|
|
|
conf()->set(Config::proxy, Config::Proxy::i2p);
|
|
|
|
conf()->set(Config::socks5Port, Prestium::i2pPort());
|
|
|
|
conf()->set(Config::hideUpdateNotifications, true);
|
2023-02-11 17:11:21 +00:00
|
|
|
}
|
|
|
|
|
2021-05-18 15:59:18 +00:00
|
|
|
if (parser.isSet("use-local-tor"))
|
2023-09-12 14:15:40 +00:00
|
|
|
conf()->set(Config::useLocalTor, true);
|
2021-05-18 15:59:18 +00:00
|
|
|
|
2023-11-30 14:01:39 +00:00
|
|
|
conf()->set(Config::restartRequired, false);
|
|
|
|
|
2021-05-18 15:59:18 +00:00
|
|
|
if (!quiet) {
|
2020-10-07 10:36:04 +00:00
|
|
|
QMap<QString, QString> info;
|
|
|
|
info["Qt"] = QT_VERSION_STR;
|
|
|
|
info["Feather"] = FEATHER_VERSION;
|
|
|
|
if (stagenet) info["Mode"] = "Stagenet";
|
|
|
|
else if (testnet) info["Mode"] = "Testnet";
|
|
|
|
else info["Mode"] = "Mainnet";
|
|
|
|
info["SSL"] = QSslSocket::sslLibraryVersionString();
|
|
|
|
info["SSL build"] = QSslSocket::sslLibraryBuildVersionString();
|
2022-02-23 16:04:23 +00:00
|
|
|
#if defined(TOR_VERSION)
|
|
|
|
info["Tor version"] = TOR_VERSION;
|
|
|
|
#else
|
|
|
|
info["Tor version"] = "Not bundled";
|
|
|
|
#endif
|
2022-02-11 11:50:09 +00:00
|
|
|
for (const QString &k: info.keys()) {
|
|
|
|
qWarning().nospace().noquote() << QString("%1: %2").arg(k, info[k]);
|
|
|
|
}
|
2020-10-07 10:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(Q_OS_MAC)
|
|
|
|
// For some odd reason, if we don't do this, QPushButton's
|
|
|
|
// need to be clicked *twice* in order to fire ?!
|
|
|
|
QFont fontDef = QApplication::font();
|
|
|
|
fontDef.setPointSize(fontDef.pointSize() + 1);
|
|
|
|
QApplication::setFont(fontDef);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
qInstallMessageHandler(Utils::applicationLogHandler);
|
2021-01-26 23:55:27 +00:00
|
|
|
qRegisterMetaType<QVector<QString>>();
|
2021-10-22 19:25:27 +00:00
|
|
|
qRegisterMetaType<TxProofResult>("TxProofResult");
|
|
|
|
qRegisterMetaType<QPair<bool, bool>>();
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2022-03-04 16:20:17 +00:00
|
|
|
EventFilter filter;
|
|
|
|
app.installEventFilter(&filter);
|
|
|
|
|
2023-03-01 20:21:48 +00:00
|
|
|
auto *pool = QThreadPool::globalInstance();
|
|
|
|
if (pool->maxThreadCount() < 8) {
|
|
|
|
pool->setMaxThreadCount(8);
|
|
|
|
}
|
|
|
|
|
2023-09-12 14:15:40 +00:00
|
|
|
auto wm = windowManager();
|
|
|
|
wm->setEventFilter(&filter);
|
2021-05-18 15:59:18 +00:00
|
|
|
|
2024-10-01 02:21:42 +00:00
|
|
|
int exitCode = Application::exec();
|
|
|
|
qDebug() << "Application::exec() returned";
|
2024-10-01 00:17:51 +00:00
|
|
|
return exitCode;
|
2020-10-07 10:36:04 +00:00
|
|
|
}
|