mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-21 17:42:37 +02:00
[gui] load PSBT
co-authored-by: Glenn Willen <gwillen@nerdnet.org>
This commit is contained in:
parent
f6895301f7
commit
1cd8dc2556
@ -317,6 +317,8 @@ void BitcoinGUI::createActions()
|
|||||||
signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
|
signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
|
||||||
verifyMessageAction = new QAction(tr("&Verify message..."), this);
|
verifyMessageAction = new QAction(tr("&Verify message..."), this);
|
||||||
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
|
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
|
||||||
|
m_load_psbt_action = new QAction(tr("Load PSBT..."), this);
|
||||||
|
m_load_psbt_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction"));
|
||||||
|
|
||||||
openRPCConsoleAction = new QAction(tr("Node window"), this);
|
openRPCConsoleAction = new QAction(tr("Node window"), this);
|
||||||
openRPCConsoleAction->setStatusTip(tr("Open node debugging and diagnostic console"));
|
openRPCConsoleAction->setStatusTip(tr("Open node debugging and diagnostic console"));
|
||||||
@ -366,6 +368,7 @@ void BitcoinGUI::createActions()
|
|||||||
connect(changePassphraseAction, &QAction::triggered, walletFrame, &WalletFrame::changePassphrase);
|
connect(changePassphraseAction, &QAction::triggered, walletFrame, &WalletFrame::changePassphrase);
|
||||||
connect(signMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
connect(signMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
||||||
connect(signMessageAction, &QAction::triggered, [this]{ gotoSignMessageTab(); });
|
connect(signMessageAction, &QAction::triggered, [this]{ gotoSignMessageTab(); });
|
||||||
|
connect(m_load_psbt_action, &QAction::triggered, [this]{ gotoLoadPSBT(); });
|
||||||
connect(verifyMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
connect(verifyMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
||||||
connect(verifyMessageAction, &QAction::triggered, [this]{ gotoVerifyMessageTab(); });
|
connect(verifyMessageAction, &QAction::triggered, [this]{ gotoVerifyMessageTab(); });
|
||||||
connect(usedSendingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedSendingAddresses);
|
connect(usedSendingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedSendingAddresses);
|
||||||
@ -438,6 +441,7 @@ void BitcoinGUI::createMenuBar()
|
|||||||
file->addAction(backupWalletAction);
|
file->addAction(backupWalletAction);
|
||||||
file->addAction(signMessageAction);
|
file->addAction(signMessageAction);
|
||||||
file->addAction(verifyMessageAction);
|
file->addAction(verifyMessageAction);
|
||||||
|
file->addAction(m_load_psbt_action);
|
||||||
file->addSeparator();
|
file->addSeparator();
|
||||||
}
|
}
|
||||||
file->addAction(quitAction);
|
file->addAction(quitAction);
|
||||||
@ -854,6 +858,10 @@ void BitcoinGUI::gotoVerifyMessageTab(QString addr)
|
|||||||
{
|
{
|
||||||
if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
|
if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
|
||||||
}
|
}
|
||||||
|
void BitcoinGUI::gotoLoadPSBT()
|
||||||
|
{
|
||||||
|
if (walletFrame) walletFrame->gotoLoadPSBT();
|
||||||
|
}
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
|
|
||||||
void BitcoinGUI::updateNetworkState()
|
void BitcoinGUI::updateNetworkState()
|
||||||
|
@ -135,6 +135,7 @@ private:
|
|||||||
QAction* usedReceivingAddressesAction = nullptr;
|
QAction* usedReceivingAddressesAction = nullptr;
|
||||||
QAction* signMessageAction = nullptr;
|
QAction* signMessageAction = nullptr;
|
||||||
QAction* verifyMessageAction = nullptr;
|
QAction* verifyMessageAction = nullptr;
|
||||||
|
QAction* m_load_psbt_action = nullptr;
|
||||||
QAction* aboutAction = nullptr;
|
QAction* aboutAction = nullptr;
|
||||||
QAction* receiveCoinsAction = nullptr;
|
QAction* receiveCoinsAction = nullptr;
|
||||||
QAction* receiveCoinsMenuAction = nullptr;
|
QAction* receiveCoinsMenuAction = nullptr;
|
||||||
@ -270,6 +271,8 @@ public Q_SLOTS:
|
|||||||
void gotoSignMessageTab(QString addr = "");
|
void gotoSignMessageTab(QString addr = "");
|
||||||
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
||||||
void gotoVerifyMessageTab(QString addr = "");
|
void gotoVerifyMessageTab(QString addr = "");
|
||||||
|
/** Show load Partially Signed Bitcoin Transaction dialog */
|
||||||
|
void gotoLoadPSBT();
|
||||||
|
|
||||||
/** Show open dialog */
|
/** Show open dialog */
|
||||||
void openClicked();
|
void openClicked();
|
||||||
|
@ -163,6 +163,14 @@ void WalletFrame::gotoVerifyMessageTab(QString addr)
|
|||||||
walletView->gotoVerifyMessageTab(addr);
|
walletView->gotoVerifyMessageTab(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WalletFrame::gotoLoadPSBT()
|
||||||
|
{
|
||||||
|
WalletView *walletView = currentWalletView();
|
||||||
|
if (walletView) {
|
||||||
|
walletView->gotoLoadPSBT();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WalletFrame::encryptWallet(bool status)
|
void WalletFrame::encryptWallet(bool status)
|
||||||
{
|
{
|
||||||
WalletView *walletView = currentWalletView();
|
WalletView *walletView = currentWalletView();
|
||||||
|
@ -78,6 +78,9 @@ public Q_SLOTS:
|
|||||||
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
||||||
void gotoVerifyMessageTab(QString addr = "");
|
void gotoVerifyMessageTab(QString addr = "");
|
||||||
|
|
||||||
|
/** Load Partially Signed Bitcoin Transaction */
|
||||||
|
void gotoLoadPSBT();
|
||||||
|
|
||||||
/** Encrypt the wallet */
|
/** Encrypt the wallet */
|
||||||
void encryptWallet(bool status);
|
void encryptWallet(bool status);
|
||||||
/** Backup the wallet */
|
/** Backup the wallet */
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
#include <qt/walletview.h>
|
#include <qt/walletview.h>
|
||||||
|
|
||||||
|
#include <node/psbt.h>
|
||||||
|
#include <node/transaction.h>
|
||||||
|
#include <policy/policy.h>
|
||||||
#include <qt/addressbookpage.h>
|
#include <qt/addressbookpage.h>
|
||||||
#include <qt/askpassphrasedialog.h>
|
#include <qt/askpassphrasedialog.h>
|
||||||
#include <qt/clientmodel.h>
|
#include <qt/clientmodel.h>
|
||||||
@ -20,6 +23,7 @@
|
|||||||
|
|
||||||
#include <interfaces/node.h>
|
#include <interfaces/node.h>
|
||||||
#include <ui_interface.h>
|
#include <ui_interface.h>
|
||||||
|
#include <util/strencodings.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
@ -197,6 +201,80 @@ void WalletView::gotoVerifyMessageTab(QString addr)
|
|||||||
signVerifyMessageDialog->setAddress_VM(addr);
|
signVerifyMessageDialog->setAddress_VM(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WalletView::gotoLoadPSBT()
|
||||||
|
{
|
||||||
|
QString filename = GUIUtil::getOpenFileName(this,
|
||||||
|
tr("Load Transaction Data"), QString(),
|
||||||
|
tr("Partially Signed Transaction (*.psbt)"), nullptr);
|
||||||
|
if (filename.isEmpty()) return;
|
||||||
|
if (GetFileSize(filename.toLocal8Bit().data(), MAX_FILE_SIZE_PSBT) == MAX_FILE_SIZE_PSBT) {
|
||||||
|
Q_EMIT message(tr("Error"), tr("PSBT file must be smaller than 100 MiB"), CClientUIInterface::MSG_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::ifstream in(filename.toLocal8Bit().data(), std::ios::binary);
|
||||||
|
std::string data(std::istreambuf_iterator<char>{in}, {});
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
PartiallySignedTransaction psbtx;
|
||||||
|
if (!DecodeRawPSBT(psbtx, data, error)) {
|
||||||
|
Q_EMIT message(tr("Error"), tr("Unable to decode PSBT file") + "\n" + QString::fromStdString(error), CClientUIInterface::MSG_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMutableTransaction mtx;
|
||||||
|
bool complete = false;
|
||||||
|
PSBTAnalysis analysis = AnalyzePSBT(psbtx);
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setText("PSBT");
|
||||||
|
switch (analysis.next) {
|
||||||
|
case PSBTRole::CREATOR:
|
||||||
|
case PSBTRole::UPDATER:
|
||||||
|
msgBox.setInformativeText("PSBT is incomplete. Copy to clipboard for manual inspection?");
|
||||||
|
break;
|
||||||
|
case PSBTRole::SIGNER:
|
||||||
|
msgBox.setInformativeText("Transaction needs more signatures. Copy to clipboard?");
|
||||||
|
break;
|
||||||
|
case PSBTRole::FINALIZER:
|
||||||
|
case PSBTRole::EXTRACTOR:
|
||||||
|
complete = FinalizeAndExtractPSBT(psbtx, mtx);
|
||||||
|
if (complete) {
|
||||||
|
msgBox.setInformativeText(tr("Would you like to send this transaction?"));
|
||||||
|
} else {
|
||||||
|
// The analyzer missed something, e.g. if there are final_scriptSig/final_scriptWitness
|
||||||
|
// but with invalid signatures.
|
||||||
|
msgBox.setInformativeText(tr("There was an unexpected problem processing the PSBT. Copy to clipboard for manual inspection?"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
|
||||||
|
switch (msgBox.exec()) {
|
||||||
|
case QMessageBox::Yes: {
|
||||||
|
if (complete) {
|
||||||
|
std::string err_string;
|
||||||
|
CTransactionRef tx = MakeTransactionRef(mtx);
|
||||||
|
|
||||||
|
TransactionError result = BroadcastTransaction(*clientModel->node().context(), tx, err_string, DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK(), /* relay */ true, /* wait_callback */ false);
|
||||||
|
if (result == TransactionError::OK) {
|
||||||
|
Q_EMIT message(tr("Success"), tr("Broadcasted transaction sucessfully."), CClientUIInterface::MSG_INFORMATION | CClientUIInterface::MODAL);
|
||||||
|
} else {
|
||||||
|
Q_EMIT message(tr("Error"), QString::fromStdString(err_string), CClientUIInterface::MSG_ERROR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Serialize the PSBT
|
||||||
|
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ssTx << psbtx;
|
||||||
|
GUIUtil::setClipboard(EncodeBase64(ssTx.str()).c_str());
|
||||||
|
Q_EMIT message(tr("PSBT copied"), "Copied to clipboard", CClientUIInterface::MSG_INFORMATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case QMessageBox::Cancel:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
|
bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
|
||||||
{
|
{
|
||||||
return sendCoinsPage->handlePaymentRequest(recipient);
|
return sendCoinsPage->handlePaymentRequest(recipient);
|
||||||
|
@ -83,6 +83,8 @@ public Q_SLOTS:
|
|||||||
void gotoSignMessageTab(QString addr = "");
|
void gotoSignMessageTab(QString addr = "");
|
||||||
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
||||||
void gotoVerifyMessageTab(QString addr = "");
|
void gotoVerifyMessageTab(QString addr = "");
|
||||||
|
/** Load Partially Signed Bitcoin Transaction */
|
||||||
|
void gotoLoadPSBT();
|
||||||
|
|
||||||
/** Show incoming transaction notification for new transactions.
|
/** Show incoming transaction notification for new transactions.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user