Skip to content

Commit 1cd8dc2

Browse files
Sjorsgwillen
andcommitted
[gui] load PSBT
co-authored-by: Glenn Willen <[email protected]>
1 parent f689530 commit 1cd8dc2

File tree

6 files changed

+102
-0
lines changed

6 files changed

+102
-0
lines changed

src/qt/bitcoingui.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ void BitcoinGUI::createActions()
317317
signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
318318
verifyMessageAction = new QAction(tr("&Verify message..."), this);
319319
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
320+
m_load_psbt_action = new QAction(tr("Load PSBT..."), this);
321+
m_load_psbt_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction"));
320322

321323
openRPCConsoleAction = new QAction(tr("Node window"), this);
322324
openRPCConsoleAction->setStatusTip(tr("Open node debugging and diagnostic console"));
@@ -366,6 +368,7 @@ void BitcoinGUI::createActions()
366368
connect(changePassphraseAction, &QAction::triggered, walletFrame, &WalletFrame::changePassphrase);
367369
connect(signMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
368370
connect(signMessageAction, &QAction::triggered, [this]{ gotoSignMessageTab(); });
371+
connect(m_load_psbt_action, &QAction::triggered, [this]{ gotoLoadPSBT(); });
369372
connect(verifyMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
370373
connect(verifyMessageAction, &QAction::triggered, [this]{ gotoVerifyMessageTab(); });
371374
connect(usedSendingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedSendingAddresses);
@@ -438,6 +441,7 @@ void BitcoinGUI::createMenuBar()
438441
file->addAction(backupWalletAction);
439442
file->addAction(signMessageAction);
440443
file->addAction(verifyMessageAction);
444+
file->addAction(m_load_psbt_action);
441445
file->addSeparator();
442446
}
443447
file->addAction(quitAction);
@@ -854,6 +858,10 @@ void BitcoinGUI::gotoVerifyMessageTab(QString addr)
854858
{
855859
if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
856860
}
861+
void BitcoinGUI::gotoLoadPSBT()
862+
{
863+
if (walletFrame) walletFrame->gotoLoadPSBT();
864+
}
857865
#endif // ENABLE_WALLET
858866

859867
void BitcoinGUI::updateNetworkState()

src/qt/bitcoingui.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ class BitcoinGUI : public QMainWindow
135135
QAction* usedReceivingAddressesAction = nullptr;
136136
QAction* signMessageAction = nullptr;
137137
QAction* verifyMessageAction = nullptr;
138+
QAction* m_load_psbt_action = nullptr;
138139
QAction* aboutAction = nullptr;
139140
QAction* receiveCoinsAction = nullptr;
140141
QAction* receiveCoinsMenuAction = nullptr;
@@ -270,6 +271,8 @@ public Q_SLOTS:
270271
void gotoSignMessageTab(QString addr = "");
271272
/** Show Sign/Verify Message dialog and switch to verify message tab */
272273
void gotoVerifyMessageTab(QString addr = "");
274+
/** Show load Partially Signed Bitcoin Transaction dialog */
275+
void gotoLoadPSBT();
273276

274277
/** Show open dialog */
275278
void openClicked();

src/qt/walletframe.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,14 @@ void WalletFrame::gotoVerifyMessageTab(QString addr)
163163
walletView->gotoVerifyMessageTab(addr);
164164
}
165165

166+
void WalletFrame::gotoLoadPSBT()
167+
{
168+
WalletView *walletView = currentWalletView();
169+
if (walletView) {
170+
walletView->gotoLoadPSBT();
171+
}
172+
}
173+
166174
void WalletFrame::encryptWallet(bool status)
167175
{
168176
WalletView *walletView = currentWalletView();

src/qt/walletframe.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ public Q_SLOTS:
7878
/** Show Sign/Verify Message dialog and switch to verify message tab */
7979
void gotoVerifyMessageTab(QString addr = "");
8080

81+
/** Load Partially Signed Bitcoin Transaction */
82+
void gotoLoadPSBT();
83+
8184
/** Encrypt the wallet */
8285
void encryptWallet(bool status);
8386
/** Backup the wallet */

src/qt/walletview.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
#include <qt/walletview.h>
66

7+
#include <node/psbt.h>
8+
#include <node/transaction.h>
9+
#include <policy/policy.h>
710
#include <qt/addressbookpage.h>
811
#include <qt/askpassphrasedialog.h>
912
#include <qt/clientmodel.h>
@@ -20,6 +23,7 @@
2023

2124
#include <interfaces/node.h>
2225
#include <ui_interface.h>
26+
#include <util/strencodings.h>
2327

2428
#include <QAction>
2529
#include <QActionGroup>
@@ -197,6 +201,80 @@ void WalletView::gotoVerifyMessageTab(QString addr)
197201
signVerifyMessageDialog->setAddress_VM(addr);
198202
}
199203

204+
void WalletView::gotoLoadPSBT()
205+
{
206+
QString filename = GUIUtil::getOpenFileName(this,
207+
tr("Load Transaction Data"), QString(),
208+
tr("Partially Signed Transaction (*.psbt)"), nullptr);
209+
if (filename.isEmpty()) return;
210+
if (GetFileSize(filename.toLocal8Bit().data(), MAX_FILE_SIZE_PSBT) == MAX_FILE_SIZE_PSBT) {
211+
Q_EMIT message(tr("Error"), tr("PSBT file must be smaller than 100 MiB"), CClientUIInterface::MSG_ERROR);
212+
return;
213+
}
214+
std::ifstream in(filename.toLocal8Bit().data(), std::ios::binary);
215+
std::string data(std::istreambuf_iterator<char>{in}, {});
216+
217+
std::string error;
218+
PartiallySignedTransaction psbtx;
219+
if (!DecodeRawPSBT(psbtx, data, error)) {
220+
Q_EMIT message(tr("Error"), tr("Unable to decode PSBT file") + "\n" + QString::fromStdString(error), CClientUIInterface::MSG_ERROR);
221+
return;
222+
}
223+
224+
CMutableTransaction mtx;
225+
bool complete = false;
226+
PSBTAnalysis analysis = AnalyzePSBT(psbtx);
227+
QMessageBox msgBox;
228+
msgBox.setText("PSBT");
229+
switch (analysis.next) {
230+
case PSBTRole::CREATOR:
231+
case PSBTRole::UPDATER:
232+
msgBox.setInformativeText("PSBT is incomplete. Copy to clipboard for manual inspection?");
233+
break;
234+
case PSBTRole::SIGNER:
235+
msgBox.setInformativeText("Transaction needs more signatures. Copy to clipboard?");
236+
break;
237+
case PSBTRole::FINALIZER:
238+
case PSBTRole::EXTRACTOR:
239+
complete = FinalizeAndExtractPSBT(psbtx, mtx);
240+
if (complete) {
241+
msgBox.setInformativeText(tr("Would you like to send this transaction?"));
242+
} else {
243+
// The analyzer missed something, e.g. if there are final_scriptSig/final_scriptWitness
244+
// but with invalid signatures.
245+
msgBox.setInformativeText(tr("There was an unexpected problem processing the PSBT. Copy to clipboard for manual inspection?"));
246+
}
247+
}
248+
249+
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
250+
switch (msgBox.exec()) {
251+
case QMessageBox::Yes: {
252+
if (complete) {
253+
std::string err_string;
254+
CTransactionRef tx = MakeTransactionRef(mtx);
255+
256+
TransactionError result = BroadcastTransaction(*clientModel->node().context(), tx, err_string, DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK(), /* relay */ true, /* wait_callback */ false);
257+
if (result == TransactionError::OK) {
258+
Q_EMIT message(tr("Success"), tr("Broadcasted transaction sucessfully."), CClientUIInterface::MSG_INFORMATION | CClientUIInterface::MODAL);
259+
} else {
260+
Q_EMIT message(tr("Error"), QString::fromStdString(err_string), CClientUIInterface::MSG_ERROR);
261+
}
262+
} else {
263+
// Serialize the PSBT
264+
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
265+
ssTx << psbtx;
266+
GUIUtil::setClipboard(EncodeBase64(ssTx.str()).c_str());
267+
Q_EMIT message(tr("PSBT copied"), "Copied to clipboard", CClientUIInterface::MSG_INFORMATION);
268+
return;
269+
}
270+
}
271+
case QMessageBox::Cancel:
272+
break;
273+
default:
274+
assert(false);
275+
}
276+
}
277+
200278
bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
201279
{
202280
return sendCoinsPage->handlePaymentRequest(recipient);

src/qt/walletview.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public Q_SLOTS:
8383
void gotoSignMessageTab(QString addr = "");
8484
/** Show Sign/Verify Message dialog and switch to verify message tab */
8585
void gotoVerifyMessageTab(QString addr = "");
86+
/** Load Partially Signed Bitcoin Transaction */
87+
void gotoLoadPSBT();
8688

8789
/** Show incoming transaction notification for new transactions.
8890

0 commit comments

Comments
 (0)