mirror of
https://github.com/feather-wallet/feather.git
synced 2024-11-17 09:47:36 +00:00
Merge pull request 'Beta-9' (#386) from tobtoht/feather:beta-9 into master
Reviewed-on: https://git.featherwallet.org/feather/feather/pulls/386
This commit is contained in:
commit
6aa7261ef4
34 changed files with 470 additions and 1728 deletions
|
@ -32,7 +32,7 @@ if(DEBUG)
|
|||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
endif()
|
||||
|
||||
set(MONERO_HEAD "d0662146e12d9c0ac9905b4423bb27bd68a4444e")
|
||||
set(MONERO_HEAD "d4257af2e7503fc6dc09fc704606230d353a0a02")
|
||||
set(BUILD_GUI_DEPS ON)
|
||||
option(ARCH "Target architecture" "x86-64")
|
||||
set(BUILD_64 ON)
|
||||
|
|
|
@ -28,9 +28,9 @@ RUN bash verify-packages.sh && \
|
|||
|
||||
# OpenSSL: Required for CMake, Qt 5.15.2, libwallet, Tor
|
||||
ENV OPENSSL_ROOT_DIR=/usr/local/openssl/
|
||||
RUN git clone -b OpenSSL_1_1_1k --depth 1 https://github.com/openssl/openssl.git && \
|
||||
RUN git clone -b OpenSSL_1_1_1l --depth 1 https://github.com/openssl/openssl.git && \
|
||||
cd openssl && \
|
||||
git reset --hard fd78df59b0f656aefe96e39533130454aa957c00 && \
|
||||
git reset --hard fb047ebc87b18bdc4cf9ddee9ee1f5ed93e56aff && \
|
||||
./config no-shared no-dso --prefix=/usr/local/openssl && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install_sw && \
|
||||
|
|
|
@ -131,11 +131,11 @@ RUN wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz && \
|
|||
rm -rf $(pwd)
|
||||
|
||||
# OpenSSL -> Tor
|
||||
RUN wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz && \
|
||||
echo "892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5 openssl-1.1.1k.tar.gz" | sha256sum -c && \
|
||||
tar -xzf openssl-1.1.1k.tar.gz && \
|
||||
rm openssl-1.1.1k.tar.gz && \
|
||||
cd openssl-1.1.1k && \
|
||||
RUN wget https://www.openssl.org/source/openssl-1.1.1l.tar.gz && \
|
||||
echo "0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1 openssl-1.1.1l.tar.gz" | sha256sum -c && \
|
||||
tar -xzf openssl-1.1.1l.tar.gz && \
|
||||
rm openssl-1.1.1l.tar.gz && \
|
||||
cd openssl-1.1.1l && \
|
||||
./Configure mingw64 no-shared no-dso --cross-compile-prefix=x86_64-w64-mingw32- --prefix=/usr/local/openssl && \
|
||||
make -j$THREADS && \
|
||||
make -j$THREADS install_sw && \
|
||||
|
|
46
contrib/generate-restore-heights/heights.py
Normal file
46
contrib/generate-restore-heights/heights.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
import requests
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Generate restore height list.')
|
||||
parser.add_argument('-P', '--port',
|
||||
default='18081',
|
||||
dest='port',
|
||||
help='Daemon port',
|
||||
type=int)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
DAEMON_ADDRESS = f"http://127.0.0.1:{args.port}"
|
||||
|
||||
def get_block_timestamp(height: int):
|
||||
data = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
"method": "get_block_header_by_height",
|
||||
"params": {
|
||||
"height": height
|
||||
}
|
||||
}
|
||||
res = requests.get(DAEMON_ADDRESS+"/json_rpc", json=data)
|
||||
return res.json()['result']['block_header']['timestamp']
|
||||
|
||||
|
||||
def get_height():
|
||||
data = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
"method": "get_block_count"
|
||||
}
|
||||
res = requests.get(DAEMON_ADDRESS+"/json_rpc", json=data)
|
||||
return res.json()['result']['count']
|
||||
|
||||
|
||||
timestamps = {}
|
||||
current_height = get_height()
|
||||
|
||||
timestamps[1] = get_block_timestamp(1)
|
||||
for height in range(1500, current_height, 1500):
|
||||
timestamps[height] = get_block_timestamp(height)
|
||||
|
||||
for val in timestamps:
|
||||
print(f"{timestamps[val]}:{val}")
|
|
@ -84,7 +84,7 @@ void HistoryWidget::showContextMenu(const QPoint &point) {
|
|||
|
||||
bool unconfirmed = tx->isFailed() || tx->isPending();
|
||||
if (unconfirmed && tx->direction() != TransactionInfo::Direction_In) {
|
||||
menu.addAction(icons()->icon("info2.svg"), "Resend transaction", this, &HistoryWidget::onResendTransaction);
|
||||
menu.addAction("Resend transaction", this, &HistoryWidget::onResendTransaction);
|
||||
}
|
||||
|
||||
menu.addMenu(m_copyMenu);
|
||||
|
@ -144,9 +144,9 @@ void HistoryWidget::createTxProof() {
|
|||
auto *tx = ui->history->currentEntry();
|
||||
if (!tx) return;
|
||||
|
||||
auto *dialog = new TxProofDialog(this, m_ctx, tx);
|
||||
dialog->exec();
|
||||
dialog->deleteLater();
|
||||
TxProofDialog dialog{this, m_ctx, tx};
|
||||
dialog.getTxKey();
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void HistoryWidget::copy(copyField field) {
|
||||
|
|
|
@ -236,7 +236,7 @@ void MainWindow::initMenu() {
|
|||
connect(ui->actionViewOnly, &QAction::triggered, this, &MainWindow::showViewOnlyDialog);
|
||||
|
||||
// [Wallet] -> [Advanced]
|
||||
connect(ui->actionStore_wallet, &QAction::triggered, [this]{m_ctx->wallet->store();});
|
||||
connect(ui->actionStore_wallet, &QAction::triggered, this, &MainWindow::tryStoreWallet);
|
||||
connect(ui->actionUpdate_balance, &QAction::triggered, [this]{m_ctx->updateBalance();});
|
||||
connect(ui->actionRefresh_tabs, &QAction::triggered, [this]{m_ctx->refreshModels();});
|
||||
connect(ui->actionRescan_spent, &QAction::triggered, this, &MainWindow::rescanSpent);
|
||||
|
@ -530,6 +530,16 @@ void MainWindow::setStatusText(const QString &text, bool override, int timeout)
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::tryStoreWallet() {
|
||||
if (m_ctx->wallet->connectionStatus() == Wallet::ConnectionStatus::ConnectionStatus_Synchronizing) {
|
||||
QMessageBox::warning(this, "Save wallet", "Unable to save wallet during synchronization.\n\n"
|
||||
"Wait until synchronization is finished and try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_ctx->wallet->store();
|
||||
}
|
||||
|
||||
void MainWindow::onSynchronized() {
|
||||
this->updateNetStats();
|
||||
this->setStatusText("Synchronized");
|
||||
|
@ -582,19 +592,17 @@ void MainWindow::onConnectionStatusChanged(int status)
|
|||
}
|
||||
|
||||
void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address) {
|
||||
auto tx_status = tx->status();
|
||||
QString err{"Can't create transaction: "};
|
||||
|
||||
if (tx_status != PendingTransaction::Status_Ok){
|
||||
if (tx->status() != PendingTransaction::Status_Ok) {
|
||||
QString tx_err = tx->errorString();
|
||||
qCritical() << tx_err;
|
||||
|
||||
if (m_ctx->wallet->connectionStatus() == Wallet::ConnectionStatus_WrongVersion)
|
||||
err = QString("%1 Wrong daemon version: %2").arg(err).arg(tx_err);
|
||||
err = QString("%1 Wrong node version: %2").arg(err).arg(tx_err);
|
||||
else
|
||||
err = QString("%1 %2").arg(err).arg(tx_err);
|
||||
|
||||
if (tx_err.contains("Daemon response did not include the requested real output")) {
|
||||
if (tx_err.contains("Node response did not include the requested real output")) {
|
||||
QString currentNode = m_ctx->nodes->connection().toAddress();
|
||||
|
||||
err += QString("\nYou are currently connected to: %1\n\n"
|
||||
|
@ -605,42 +613,43 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QVecto
|
|||
qDebug() << Q_FUNC_INFO << err;
|
||||
this->displayWalletErrorMsg(err);
|
||||
m_ctx->wallet->disposeTransaction(tx);
|
||||
return;
|
||||
}
|
||||
else if (tx->txCount() == 0) {
|
||||
err = QString("%1 %2").arg(err).arg("No unmixable outputs to sweep.");
|
||||
qDebug() << Q_FUNC_INFO << err;
|
||||
this->displayWalletErrorMsg(err);
|
||||
m_ctx->wallet->disposeTransaction(tx);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
const auto &description = m_ctx->tmpTxDescription;
|
||||
|
||||
// Show advanced dialog on multi-destination transactions
|
||||
if (address.size() > 1) {
|
||||
TxConfAdvDialog dialog_adv{m_ctx, description, this};
|
||||
dialog_adv.setTransaction(tx);
|
||||
dialog_adv.exec();
|
||||
return;
|
||||
}
|
||||
m_ctx->addCacheTransaction(tx->txid()[0], tx->signedTxToHex(0));
|
||||
|
||||
TxConfDialog dialog{m_ctx, tx, address[0], description, this};
|
||||
switch (dialog.exec()) {
|
||||
case QDialog::Rejected:
|
||||
{
|
||||
if (!dialog.showAdvanced)
|
||||
m_ctx->onCancelTransaction(tx, address);
|
||||
break;
|
||||
}
|
||||
case QDialog::Accepted:
|
||||
m_ctx->commitTransaction(tx);
|
||||
break;
|
||||
}
|
||||
// Show advanced dialog on multi-destination transactions
|
||||
if (address.size() > 1) {
|
||||
TxConfAdvDialog dialog_adv{m_ctx, m_ctx->tmpTxDescription, this};
|
||||
dialog_adv.setTransaction(tx);
|
||||
dialog_adv.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
if (dialog.showAdvanced) {
|
||||
TxConfAdvDialog dialog_adv{m_ctx, description, this};
|
||||
dialog_adv.setTransaction(tx);
|
||||
dialog_adv.exec();
|
||||
TxConfDialog dialog{m_ctx, tx, address[0], m_ctx->tmpTxDescription, this};
|
||||
switch (dialog.exec()) {
|
||||
case QDialog::Rejected:
|
||||
{
|
||||
if (!dialog.showAdvanced)
|
||||
m_ctx->onCancelTransaction(tx, address);
|
||||
break;
|
||||
}
|
||||
case QDialog::Accepted:
|
||||
m_ctx->commitTransaction(tx);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dialog.showAdvanced) {
|
||||
TxConfAdvDialog dialog_adv{m_ctx, m_ctx->tmpTxDescription, this};
|
||||
dialog_adv.setTransaction(tx);
|
||||
dialog_adv.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,7 +725,7 @@ void MainWindow::showConnectionStatusDialog() {
|
|||
QString statusMsg;
|
||||
switch(status){
|
||||
case Wallet::ConnectionStatus_Disconnected:
|
||||
statusMsg = "Wallet is disconnected from daemon.";
|
||||
statusMsg = "Wallet is disconnected from node.";
|
||||
break;
|
||||
case Wallet::ConnectionStatus_Connecting: {
|
||||
auto node = m_ctx->nodes->connection();
|
||||
|
@ -724,7 +733,7 @@ void MainWindow::showConnectionStatusDialog() {
|
|||
break;
|
||||
}
|
||||
case Wallet::ConnectionStatus_WrongVersion:
|
||||
statusMsg = "Wallet is connected to incompatible daemon.";
|
||||
statusMsg = "Wallet is connected to incompatible node.";
|
||||
break;
|
||||
case Wallet::ConnectionStatus_Synchronizing:
|
||||
case Wallet::ConnectionStatus_Synchronized: {
|
||||
|
|
|
@ -180,6 +180,7 @@ private slots:
|
|||
void onUpdatesAvailable(const QJsonObject &updates);
|
||||
void toggleSearchbar(bool enabled);
|
||||
void onSetStatusText(const QString &text);
|
||||
void tryStoreWallet();
|
||||
|
||||
private:
|
||||
friend WindowManager;
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="btn_generateSubaddress">
|
||||
<property name="text">
|
||||
<string>Generate Subaddress</string>
|
||||
<string>Create new address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -413,6 +413,11 @@
|
|||
<string>xmrchain.net</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>melo.tools</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>moneroblocks.info</string>
|
||||
|
@ -423,6 +428,11 @@
|
|||
<string>blockchair.com</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>blkchairbknpn73cfjhevhla7rkp4ed5gg2knctvv7it4lioy22defid.onion</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
|
|
@ -190,7 +190,7 @@ void WindowManager::onWalletOpenPasswordRequired(bool invalidPassword, const QSt
|
|||
case QDialog::Rejected:
|
||||
{
|
||||
m_openWalletTriedOnce = false;
|
||||
this->showWizard(WalletWizard::Page_OpenWallet);
|
||||
m_wizard->show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ bool WindowManager::autoOpenWallet() {
|
|||
|
||||
// ######################## WALLET CREATION ########################
|
||||
|
||||
void WindowManager::tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password,
|
||||
void WindowManager::tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedLanguage,
|
||||
const QString &seedOffset) {
|
||||
if(Utils::fileExists(path)) {
|
||||
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
||||
|
|
|
@ -45,7 +45,7 @@ private slots:
|
|||
void onWalletPassphraseNeeded(bool on_device);
|
||||
|
||||
private:
|
||||
void tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset);
|
||||
void tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedLanguage, const QString &seedOffset);
|
||||
void tryCreateWalletFromDevice(const QString &path, const QString &password, const QString &deviceName, int restoreHeight);
|
||||
void tryCreateWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
|
||||
|
||||
|
|
|
@ -119,7 +119,6 @@
|
|||
<file>assets/images/xmrig.ico</file>
|
||||
<file>assets/images/xmrig.svg</file>
|
||||
<file>assets/images/zoom.png</file>
|
||||
<file>assets/mnemonic_25_english.txt</file>
|
||||
<file>assets/restore_heights_monero_mainnet.txt</file>
|
||||
<file>assets/restore_heights_monero_stagenet.txt</file>
|
||||
</qresource>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,13 +1,12 @@
|
|||
{
|
||||
"mainnet": {
|
||||
"tor": [
|
||||
"monero26mmldsallmxok2kwamne4ve3mybvvn2yijsvss7ey63hc4yyd.onion:18081",
|
||||
"mxcd4577fldb3ppzy7obmmhnu3tf57gbcbd4qhwr2kxyjj2qi3dnbfqd.onion:18081",
|
||||
"moneroxmrxw44lku6qniyarpwgznpcwml4drq7vb24ppatlcg4kmxpqd.onion:18089",
|
||||
"3hvpnd4xejtzcuowvru2wfjum5wjf7synigm44rrizr3k4v5vzam2bad.onion:18081",
|
||||
"rbpgdckle3h3vi4wwwrh75usqtoc5r3alohy7yyx57isynvay63nacyd.onion:18089",
|
||||
"6dsdenp6vjkvqzy4wzsnzn6wixkdzihx3khiumyzieauxuxslmcaeiad.onion:18081",
|
||||
"56wl7y2ebhamkkiza4b7il4mrzwtyvpdym7bm2bkg3jrei2je646k3qd.onion:18089"
|
||||
"56wl7y2ebhamkkiza4b7il4mrzwtyvpdym7bm2bkg3jrei2je646k3qd.onion:18089",
|
||||
"melo7jwjspngus3xhbt5kxeqc4njhokyvh55jfmehplglgmb7a6rb6yd.onion:18081"
|
||||
],
|
||||
"clearnet": [
|
||||
"node.melo.tools:18081",
|
||||
|
@ -25,14 +24,17 @@
|
|||
]
|
||||
},
|
||||
"testnet": {
|
||||
"tor": [],
|
||||
"tor": [
|
||||
"melot6vncfusj5gfi73gaosea2mc572n3n7f7gof75zkwg6oibkhk3id.onion:28081"
|
||||
],
|
||||
"clearnet": [
|
||||
"testnet.melo.tools:28081"
|
||||
]
|
||||
},
|
||||
"stagenet": {
|
||||
"tor": [
|
||||
"ct36dsbe3oubpbebpxmiqz4uqk6zb6nhmkhoekileo4fts23rvuse2qd.onion:38081"
|
||||
"ct36dsbe3oubpbebpxmiqz4uqk6zb6nhmkhoekileo4fts23rvuse2qd.onion:38081",
|
||||
"melos2hbwolcavwbgytdwbmcx7t3uh2eu36p3vnbttibosnpzmtp6hqd.onion:38081"
|
||||
],
|
||||
"clearnet": [
|
||||
"super.fast.node.xmr.pm:38089",
|
||||
|
|
|
@ -1509,4 +1509,118 @@
|
|||
1609151786:2262000
|
||||
1609331787:2263500
|
||||
1609513572:2265000
|
||||
1609692129:2266500
|
||||
1609692129:2266500
|
||||
1609867599:2268000
|
||||
1610047219:2269500
|
||||
1610228186:2271000
|
||||
1610407595:2272500
|
||||
1610589258:2274000
|
||||
1610772298:2275500
|
||||
1610951384:2277000
|
||||
1611133107:2278500
|
||||
1611312080:2280000
|
||||
1611490215:2281500
|
||||
1611673294:2283000
|
||||
1611853050:2284500
|
||||
1612029885:2286000
|
||||
1612206719:2287500
|
||||
1612387526:2289000
|
||||
1612569532:2290500
|
||||
1612750081:2292000
|
||||
1612930978:2293500
|
||||
1613113853:2295000
|
||||
1613289586:2296500
|
||||
1613470569:2298000
|
||||
1613650566:2299500
|
||||
1613830056:2301000
|
||||
1614009139:2302500
|
||||
1614188174:2304000
|
||||
1614364622:2305500
|
||||
1614547318:2307000
|
||||
1614725907:2308500
|
||||
1614906615:2310000
|
||||
1615094144:2311500
|
||||
1615272359:2313000
|
||||
1615451290:2314500
|
||||
1615629691:2316000
|
||||
1615805209:2317500
|
||||
1615991354:2319000
|
||||
1616169054:2320500
|
||||
1616349055:2322000
|
||||
1616525847:2323500
|
||||
1616708533:2325000
|
||||
1616893535:2326500
|
||||
1617071845:2328000
|
||||
1617249163:2329500
|
||||
1617430317:2331000
|
||||
1617607600:2332500
|
||||
1617790288:2334000
|
||||
1617973699:2335500
|
||||
1618147282:2337000
|
||||
1618329866:2338500
|
||||
1618511460:2340000
|
||||
1618685970:2341500
|
||||
1618865550:2343000
|
||||
1619048569:2344500
|
||||
1619230022:2346000
|
||||
1619407133:2347500
|
||||
1619590095:2349000
|
||||
1619769449:2350500
|
||||
1619948697:2352000
|
||||
1620131734:2353500
|
||||
1620308138:2355000
|
||||
1620490090:2356500
|
||||
1620668363:2358000
|
||||
1620849947:2359500
|
||||
1621033633:2361000
|
||||
1621207215:2362500
|
||||
1621393360:2364000
|
||||
1621567773:2365500
|
||||
1621750649:2367000
|
||||
1621933277:2368500
|
||||
1622108971:2370000
|
||||
1622288557:2371500
|
||||
1622467139:2373000
|
||||
1622651471:2374500
|
||||
1622833171:2376000
|
||||
1623011441:2377500
|
||||
1623188483:2379000
|
||||
1623370163:2380500
|
||||
1623550839:2382000
|
||||
1623728565:2383500
|
||||
1623910801:2385000
|
||||
1624094652:2386500
|
||||
1624268730:2388000
|
||||
1624454173:2389500
|
||||
1624633102:2391000
|
||||
1624813544:2392500
|
||||
1624995509:2394000
|
||||
1625174760:2395500
|
||||
1625350875:2397000
|
||||
1625530310:2398500
|
||||
1625715884:2400000
|
||||
1625890512:2401500
|
||||
1626080398:2403000
|
||||
1626251832:2404500
|
||||
1626434873:2406000
|
||||
1626616459:2407500
|
||||
1626797788:2409000
|
||||
1626976609:2410500
|
||||
1627159689:2412000
|
||||
1627336518:2413500
|
||||
1627515996:2415000
|
||||
1627696970:2416500
|
||||
1627873363:2418000
|
||||
1628056769:2419500
|
||||
1628233063:2421000
|
||||
1628413022:2422500
|
||||
1628596304:2424000
|
||||
1628777705:2425500
|
||||
1628957276:2427000
|
||||
1629135964:2428500
|
||||
1629318052:2430000
|
||||
1629495981:2431500
|
||||
1629677343:2433000
|
||||
1629854603:2434500
|
||||
1630032622:2436000
|
||||
1630217808:2437500
|
|
@ -528,4 +528,81 @@
|
|||
1615573554:790500
|
||||
1615731420:792000
|
||||
1615933315:793500
|
||||
1616104918:795000
|
||||
1616104918:795000
|
||||
1616280486:796500
|
||||
1616483958:798000
|
||||
1616677488:799500
|
||||
1616864492:801000
|
||||
1617011783:802500
|
||||
1617243009:804000
|
||||
1617434167:805500
|
||||
1617609667:807000
|
||||
1617795845:808500
|
||||
1617993128:810000
|
||||
1618181526:811500
|
||||
1618362660:813000
|
||||
1618537048:814500
|
||||
1618700152:816000
|
||||
1618891334:817500
|
||||
1619058998:819000
|
||||
1619232663:820500
|
||||
1619427622:822000
|
||||
1619628127:823500
|
||||
1619863363:825000
|
||||
1619998315:826500
|
||||
1620216657:828000
|
||||
1620416386:829500
|
||||
1620602417:831000
|
||||
1620784230:832500
|
||||
1620977670:834000
|
||||
1621176309:835500
|
||||
1621352150:837000
|
||||
1621529837:838500
|
||||
1621715183:840000
|
||||
1621891016:841500
|
||||
1622068671:843000
|
||||
1622236700:844500
|
||||
1622393818:846000
|
||||
1622572603:847500
|
||||
1622767566:849000
|
||||
1622941282:850500
|
||||
1623107663:852000
|
||||
1623352063:853500
|
||||
1623502520:855000
|
||||
1623696345:856500
|
||||
1623903078:858000
|
||||
1624067589:859500
|
||||
1624277066:861000
|
||||
1624466865:862500
|
||||
1624643841:864000
|
||||
1624818125:865500
|
||||
1625006084:867000
|
||||
1625182383:868500
|
||||
1625348128:870000
|
||||
1625542485:871500
|
||||
1625690595:873000
|
||||
1625875030:874500
|
||||
1626049431:876000
|
||||
1626230916:877500
|
||||
1626454343:879000
|
||||
1626627856:880500
|
||||
1626839863:882000
|
||||
1627022662:883500
|
||||
1627206043:885000
|
||||
1627390139:886500
|
||||
1627549087:888000
|
||||
1627727762:889500
|
||||
1627910975:891000
|
||||
1628095914:892500
|
||||
1628304203:894000
|
||||
1628485223:895500
|
||||
1628636024:897000
|
||||
1628850117:898500
|
||||
1629035762:900000
|
||||
1629206719:901500
|
||||
1629395524:903000
|
||||
1629579720:904500
|
||||
1629754526:906000
|
||||
1629907575:907500
|
||||
1630095527:909000
|
||||
1630287335:910500
|
|
@ -19,6 +19,7 @@ TxConfAdvDialog::TxConfAdvDialog(QSharedPointer<AppContext> ctx, const QString &
|
|||
, m_ctx(std::move(ctx))
|
||||
, m_exportUnsignedMenu(new QMenu(this))
|
||||
, m_exportSignedMenu(new QMenu(this))
|
||||
, m_exportTxKeyMenu(new QMenu(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -31,6 +32,9 @@ TxConfAdvDialog::TxConfAdvDialog(QSharedPointer<AppContext> ctx, const QString &
|
|||
m_exportSignedMenu->addAction("Save to file", this, &TxConfAdvDialog::signedSaveFile);
|
||||
ui->btn_exportSigned->setMenu(m_exportSignedMenu);
|
||||
|
||||
m_exportTxKeyMenu->addAction("Copy to clipboard", this, &TxConfAdvDialog::txKeyCopy);
|
||||
ui->btn_exportTxKey->setMenu(m_exportTxKeyMenu);
|
||||
|
||||
if (m_ctx->wallet->viewOnly()) {
|
||||
ui->btn_exportSigned->hide();
|
||||
ui->btn_send->hide();
|
||||
|
@ -80,6 +84,7 @@ void TxConfAdvDialog::setUnsignedTransaction(UnsignedTransaction *utx) {
|
|||
|
||||
ui->btn_exportUnsigned->hide();
|
||||
ui->btn_exportSigned->hide();
|
||||
ui->btn_exportTxKey->hide();
|
||||
ui->btn_sign->show();
|
||||
ui->btn_send->hide();
|
||||
|
||||
|
@ -166,6 +171,10 @@ void TxConfAdvDialog::signedCopy() {
|
|||
Utils::copyToClipboard(m_tx->signedTxToHex(0));
|
||||
}
|
||||
|
||||
void TxConfAdvDialog::txKeyCopy() {
|
||||
Utils::copyToClipboard(m_tx->transaction(0)->txKey());
|
||||
}
|
||||
|
||||
void TxConfAdvDialog::signedQrCode() {
|
||||
}
|
||||
|
||||
|
|
|
@ -41,12 +41,15 @@ private:
|
|||
void signedQrCode();
|
||||
void signedSaveFile();
|
||||
|
||||
void txKeyCopy();
|
||||
|
||||
QScopedPointer<Ui::TxConfAdvDialog> ui;
|
||||
QSharedPointer<AppContext> m_ctx;
|
||||
PendingTransaction *m_tx = nullptr;
|
||||
UnsignedTransaction *m_utx = nullptr;
|
||||
QMenu *m_exportUnsignedMenu;
|
||||
QMenu *m_exportSignedMenu;
|
||||
QMenu *m_exportTxKeyMenu;
|
||||
};
|
||||
|
||||
#endif //FEATHER_TXCONFADVDIALOG_H
|
||||
|
|
|
@ -21,19 +21,30 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Transaction ID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Transaction ID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="txid">
|
||||
<property name="text">
|
||||
<string>txid</string>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="txid">
|
||||
<property name="text">
|
||||
<string>txid</string>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -251,6 +262,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btn_exportTxKey">
|
||||
<property name="text">
|
||||
<string>Export tx key</string>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -272,16 +293,16 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_send">
|
||||
<widget class="QPushButton" name="btn_close">
|
||||
<property name="text">
|
||||
<string>Send</string>
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_close">
|
||||
<widget class="QPushButton" name="btn_send">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
<string>Send</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -72,12 +72,10 @@ TxConfDialog::TxConfDialog(QSharedPointer<AppContext> ctx, PendingTransaction *t
|
|||
ui->label_address->setToolTip("Wallet change/primary address");
|
||||
}
|
||||
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setText("Send");
|
||||
|
||||
connect(ui->btn_Advanced, &QPushButton::clicked, this, &TxConfDialog::setShowAdvanced);
|
||||
|
||||
m_ctx->addCacheTransaction(tx->txid()[0], tx->signedTxToHex(0)); // Todo: Iterate over all txs
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,14 @@ TxImportDialog::TxImportDialog(QWidget *parent, QSharedPointer<AppContext> ctx)
|
|||
|
||||
void TxImportDialog::loadTx() {
|
||||
QString txid = ui->line_txid->text();
|
||||
|
||||
if (m_ctx->wallet->haveTransaction(txid)) {
|
||||
QMessageBox::warning(this, "Warning", "This transaction already exists in the wallet. "
|
||||
"If you can't find it in your history, "
|
||||
"check if it belongs to a different account (Wallet -> Account)");
|
||||
return;
|
||||
}
|
||||
|
||||
FeatherNode node = m_ctx->nodes->connection();
|
||||
|
||||
if (node.isLocal()) {
|
||||
|
@ -94,6 +102,10 @@ void TxImportDialog::onImport() {
|
|||
bool double_spend_seen = tx.value("double_spend_seen").toBool();
|
||||
|
||||
if (m_ctx->wallet->importTransaction(tx.value("tx_hash").toString(), output_indices, height, timestamp, false, pool, double_spend_seen)) {
|
||||
if (!m_ctx->wallet->haveTransaction(txid)) {
|
||||
QMessageBox::warning(this, "Import transaction", "This transaction does not belong to this wallet.");
|
||||
return;
|
||||
}
|
||||
QMessageBox::information(this, "Import transaction", "Transaction imported successfully.");
|
||||
} else {
|
||||
QMessageBox::warning(this, "Import transaction", "Transaction import failed.");
|
||||
|
|
|
@ -22,7 +22,11 @@ ViewOnlyDialog::ViewOnlyDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
|
|||
connect(ui->btn_Copy, &QPushButton::clicked, this, &ViewOnlyDialog::copyToClipboad);
|
||||
connect(ui->btn_Save, &QPushButton::clicked, this, &ViewOnlyDialog::onWriteViewOnlyWallet);
|
||||
|
||||
ui->btn_Save->setEnabled(!m_ctx->wallet->viewOnly());
|
||||
if (m_ctx->wallet->viewOnly()) {
|
||||
ui->btn_Save->setEnabled(false);
|
||||
ui->btn_Save->setToolTip("Wallet is already view-only");
|
||||
}
|
||||
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,9 @@
|
|||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -601,6 +601,11 @@ QString Wallet::printScannedPoolTxs()
|
|||
return QString::fromStdString(m_walletImpl->printScannedPoolTxs());
|
||||
}
|
||||
|
||||
bool Wallet::haveTransaction(const QString &txid)
|
||||
{
|
||||
return m_walletImpl->haveTransaction(txid.toStdString());
|
||||
}
|
||||
|
||||
void Wallet::startRefresh()
|
||||
{
|
||||
m_refreshEnabled = true;
|
||||
|
|
|
@ -246,6 +246,9 @@ public:
|
|||
QString printAddressBook();
|
||||
QString printScannedPoolTxs();
|
||||
|
||||
//! does wallet have txid
|
||||
bool haveTransaction(const QString &txid);
|
||||
|
||||
//! refreshes the wallet
|
||||
bool refresh(bool historyAndSubaddresses = false);
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
|||
}
|
||||
|
||||
// Setup logging
|
||||
QString logPath = QString("%1/daemon.log").arg(configDir);
|
||||
QString logPath = QString("%1/libwallet.log").arg(configDir);
|
||||
Monero::Utils::onStartup();
|
||||
Monero::Wallet::init("", "feather", logPath.toStdString(), true);
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ bool dirExists(const QString &path) {
|
|||
|
||||
QString defaultWalletDir() {
|
||||
QString portablePath = QCoreApplication::applicationDirPath().append("/%1");
|
||||
if (QFile::exists(portablePath.arg(".portable"))) {
|
||||
if (QFile::exists(portablePath.arg(".portable")) || QFile::exists(portablePath.arg(".portable.txt"))) {
|
||||
return portablePath.arg("feather_data/wallets");
|
||||
}
|
||||
|
||||
|
@ -357,6 +357,21 @@ QString blockExplorerLink(const QString &blockExplorer, NetworkType::Type nettyp
|
|||
return QString("https://blockchair.com/monero/transaction/%1").arg(txid);
|
||||
}
|
||||
}
|
||||
else if (blockExplorer == "melo.tools") {
|
||||
switch (nettype) {
|
||||
case NetworkType::MAINNET:
|
||||
return QString("https://melo.tools/explorer/mainnet/tx/%1").arg(txid);
|
||||
case NetworkType::STAGENET:
|
||||
return QString("https://melo.tools/explorer/stagenet/tx/%1").arg(txid);
|
||||
case NetworkType::TESTNET:
|
||||
return QString("https://melo.tools/explorer/testnet/tx/%1").arg(txid);
|
||||
}
|
||||
}
|
||||
else if (blockExplorer == "blkchairbknpn73cfjhevhla7rkp4ed5gg2knctvv7it4lioy22defid.onion") {
|
||||
if (nettype == NetworkType::MAINNET) {
|
||||
return QString("http://blkchairbknpn73cfjhevhla7rkp4ed5gg2knctvv7it4lioy22defid.onion/monero/transaction/%1").arg(txid);
|
||||
}
|
||||
}
|
||||
|
||||
switch (nettype) {
|
||||
case NetworkType::MAINNET:
|
||||
|
|
|
@ -158,7 +158,7 @@ Config::Config(QObject* parent)
|
|||
|
||||
QDir Config::defaultConfigDir() {
|
||||
QString portablePath = QCoreApplication::applicationDirPath().append("/%1");
|
||||
if (QFile::exists(portablePath.arg(".portable"))) {
|
||||
if (QFile::exists(portablePath.arg(".portable")) || QFile::exists(portablePath.arg(".portable.txt"))) {
|
||||
return portablePath.arg("feather_data");
|
||||
}
|
||||
|
||||
|
|
|
@ -135,8 +135,9 @@ void NodeWidget::onCustomAddClicked(){
|
|||
auto currentNodes = m_ctx->nodes->customNodes();
|
||||
QString currentNodesText;
|
||||
|
||||
for (auto &entry: currentNodes)
|
||||
currentNodesText += QString("%1\n").arg(entry.url.toString());
|
||||
for (auto &entry: currentNodes) {
|
||||
currentNodesText += QString("%1\n").arg(entry.toFullAddress());
|
||||
}
|
||||
|
||||
bool ok;
|
||||
QString text = QInputDialog::getMultiLineText(this, "Add custom node(s).", "E.g: user:password@127.0.0.1:18081", currentNodesText, &ok);
|
||||
|
@ -145,9 +146,9 @@ void NodeWidget::onCustomAddClicked(){
|
|||
|
||||
QList<FeatherNode> nodesList;
|
||||
auto newNodesList = text.split("\n");
|
||||
for(auto &newNodeText: newNodesList) {
|
||||
for (auto &newNodeText: newNodesList) {
|
||||
newNodeText = newNodeText.replace("\r", "").trimmed();
|
||||
if(newNodeText.isEmpty())
|
||||
if (newNodeText.isEmpty())
|
||||
continue;
|
||||
|
||||
auto node = FeatherNode(newNodeText);
|
||||
|
|
|
@ -12,13 +12,27 @@
|
|||
#include "utils/FeatherSeed.h"
|
||||
#include "constants.h"
|
||||
|
||||
#include <mnemonics/electrum-words.h>
|
||||
|
||||
PageWalletRestoreSeed::PageWalletRestoreSeed(WizardFields *fields, QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
, ui(new Ui::PageWalletRestoreSeed)
|
||||
, m_fields(fields)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->label_errorString->hide();
|
||||
|
||||
std::vector<const Language::Base*> wordlists = crypto::ElectrumWords::get_language_list();
|
||||
for (const auto& wordlist: wordlists) {
|
||||
QStringList words_qt;
|
||||
std::vector<std::string> words_std = wordlist->get_word_list();
|
||||
for (const auto& word: words_std) {
|
||||
words_qt += QString::fromStdString(word);
|
||||
}
|
||||
|
||||
QString language = QString::fromStdString(wordlist->get_english_language_name());
|
||||
ui->combo_seedLanguage->addItem(language);
|
||||
m_wordlists[language] = words_qt;
|
||||
}
|
||||
|
||||
QStringList bip39English;
|
||||
for (int i = 0; i != 2048; i++)
|
||||
|
@ -27,26 +41,18 @@ PageWalletRestoreSeed::PageWalletRestoreSeed(WizardFields *fields, QWidget *pare
|
|||
// (illegible word with a known location). This can be tested by replacing a word with xxxx
|
||||
bip39English << "xxxx";
|
||||
|
||||
QByteArray data = Utils::fileOpen(":/assets/mnemonic_25_english.txt");
|
||||
QStringList moneroEnglish;
|
||||
for (const auto &seed_word: data.split('\n'))
|
||||
moneroEnglish << seed_word;
|
||||
|
||||
m_tevador.length = 14;
|
||||
m_tevador.setWords(bip39English);
|
||||
|
||||
m_legacy.length = 25;
|
||||
m_legacy.setWords(moneroEnglish);
|
||||
m_legacy.setWords(m_wordlists["English"]);
|
||||
ui->combo_seedLanguage->setCurrentText("English");
|
||||
|
||||
ui->seedEdit->setAcceptRichText(false);
|
||||
ui->seedEdit->setMaximumHeight(150);
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
#endif
|
||||
|
||||
connect(ui->seedBtnGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this, &PageWalletRestoreSeed::onSeedTypeToggled);
|
||||
connect(ui->combo_seedLanguage, &QComboBox::currentTextChanged, this, &PageWalletRestoreSeed::onSeedLanguageChanged);
|
||||
|
||||
this->onSeedTypeToggled();
|
||||
}
|
||||
|
@ -56,11 +62,13 @@ void PageWalletRestoreSeed::onSeedTypeToggled() {
|
|||
m_mode = &m_tevador;
|
||||
m_fields->seedType = SeedType::TEVADOR;
|
||||
ui->seedEdit->setPlaceholderText("Enter 14 word seed..");
|
||||
ui->group_seedLanguage->hide();
|
||||
}
|
||||
else if (ui->radio25->isChecked()) {
|
||||
m_mode = &m_legacy;
|
||||
m_fields->seedType = SeedType::MONERO;
|
||||
ui->seedEdit->setPlaceholderText("Enter 25 word seed..");
|
||||
ui->group_seedLanguage->show();
|
||||
}
|
||||
|
||||
ui->label_errorString->hide();
|
||||
|
@ -69,6 +77,11 @@ void PageWalletRestoreSeed::onSeedTypeToggled() {
|
|||
ui->seedEdit->setText("");
|
||||
}
|
||||
|
||||
void PageWalletRestoreSeed::onSeedLanguageChanged(const QString &language) {
|
||||
m_legacy.setWords(m_wordlists[language]);
|
||||
m_fields->seedLanguage = language;
|
||||
}
|
||||
|
||||
int PageWalletRestoreSeed::nextId() const {
|
||||
if (m_mode == &m_legacy) {
|
||||
return WalletWizard::Page_SetRestoreHeight;
|
||||
|
@ -90,8 +103,8 @@ bool PageWalletRestoreSeed::validatePage() {
|
|||
ui->seedEdit->setStyleSheet("");
|
||||
|
||||
auto errStyle = "QTextEdit{border: 1px solid red;}";
|
||||
auto seed = ui->seedEdit->toPlainText().replace("\n", "").replace("\r", "").trimmed();
|
||||
auto seedSplit = seed.split(" ");
|
||||
auto seed = ui->seedEdit->toPlainText().replace("\n", " ").replace("\r", "").trimmed();
|
||||
QStringList seedSplit = seed.split(" ", Qt::SkipEmptyParts);
|
||||
|
||||
if (seedSplit.length() != m_mode->length) {
|
||||
ui->label_errorString->show();
|
||||
|
@ -100,8 +113,14 @@ bool PageWalletRestoreSeed::validatePage() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// libwallet will accept e.g. "brötchen" or "BRÖTCHEN" instead of "Brötchen"
|
||||
QStringList lowercaseWords;
|
||||
for (const auto &word : m_mode->words) {
|
||||
lowercaseWords << word.toLower();
|
||||
}
|
||||
|
||||
for (const auto &word : seedSplit) {
|
||||
if (!m_mode->words.contains(word)) {
|
||||
if (!lowercaseWords.contains(word.toLower())) {
|
||||
ui->label_errorString->show();
|
||||
ui->label_errorString->setText(QString("Mnemonic seed contains an unknown word: %1").arg(word));
|
||||
ui->seedEdit->setStyleSheet(errStyle);
|
||||
|
@ -119,7 +138,7 @@ bool PageWalletRestoreSeed::validatePage() {
|
|||
QMessageBox::information(this, "Corrected erasure", QString("xxxx -> %1").arg(_seed.correction));
|
||||
}
|
||||
|
||||
m_fields->seed = seed;
|
||||
m_fields->seed = seedSplit.join(" ");
|
||||
m_fields->seedOffsetPassphrase = ui->line_seedOffset->text();
|
||||
|
||||
return true;
|
||||
|
|
|
@ -32,8 +32,8 @@ private:
|
|||
seedType()
|
||||
{
|
||||
completer.setModel(&completerModel);
|
||||
completer.setModelSorting(QCompleter::CaseInsensitivelySortedModel);
|
||||
completer.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
completer.setModelSorting(QCompleter::CaseSensitivelySortedModel);
|
||||
completer.setCaseSensitivity(Qt::CaseSensitive);
|
||||
completer.setWrapAround(false);
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ private:
|
|||
};
|
||||
|
||||
void onSeedTypeToggled();
|
||||
void onSeedLanguageChanged(const QString &language);
|
||||
|
||||
Ui::PageWalletRestoreSeed *ui;
|
||||
WizardFields *m_fields;
|
||||
|
@ -57,6 +58,8 @@ private:
|
|||
seedType m_legacy;
|
||||
|
||||
seedType *m_mode;
|
||||
|
||||
QMap<QString, QStringList> m_wordlists;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,18 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="group_seedLanguage">
|
||||
<property name="title">
|
||||
<string>Select seed language:</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="combo_seedLanguage"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="TextEdit" name="seedEdit">
|
||||
<property name="acceptRichText">
|
||||
|
|
|
@ -127,5 +127,5 @@ void WalletWizard::onCreateWallet() {
|
|||
if (m_wizardFields.mode == WizardMode::RestoreFromSeed && m_wizardFields.seedType == SeedType::MONERO)
|
||||
seed.setRestoreHeight(m_wizardFields.restoreHeight);
|
||||
|
||||
emit createWallet(seed, walletPath, m_wizardFields.password, m_wizardFields.seedOffsetPassphrase);
|
||||
emit createWallet(seed, walletPath, m_wizardFields.password, m_wizardFields.seedLanguage, m_wizardFields.seedOffsetPassphrase);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "model/WalletKeysFilesModel.h"
|
||||
#include "utils/RestoreHeightLookup.h"
|
||||
#include "utils/config.h"
|
||||
#include "constants.h"
|
||||
|
||||
enum WizardMode {
|
||||
CreateWallet = 0,
|
||||
|
@ -32,6 +33,7 @@ struct WizardFields {
|
|||
QString walletDir;
|
||||
QString seed;
|
||||
QString seedOffsetPassphrase;
|
||||
QString seedLanguage = constants::seedLanguage;
|
||||
QString password;
|
||||
QString modeText;
|
||||
QString address;
|
||||
|
@ -72,7 +74,7 @@ signals:
|
|||
|
||||
void createWalletFromDevice(const QString &path, const QString &password, const QString &deviceName, int restoreHeight);
|
||||
void createWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight, bool deterministic = false);
|
||||
void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset = "");
|
||||
void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedLanguage, const QString &seedOffset = "");
|
||||
|
||||
private slots:
|
||||
void onCreateWallet();
|
||||
|
|
Loading…
Reference in a new issue