mirror of
https://github.com/monero-project/monero.git
synced 2026-01-14 22:03:25 -08:00
WalletApi: getMultisigInfo entry for gui wallets
WalletApi: makeMultisig call introduced WalletApi: finalizeMultisig call introduced WalletApi: new calls exportMultisigImages and importMultisigImages WalletApi: method to return multisig wallet creation state WalletApi: create multisig transaction, sign multisig transaction, commit transaction and get multisig data are added WalletApi: identation and style fixes
This commit is contained in:
@@ -77,6 +77,36 @@ namespace {
|
||||
dir /= ".shared-ringdb";
|
||||
return dir.string();
|
||||
}
|
||||
|
||||
void checkMultisigWalletReady(const tools::wallet2* wallet) {
|
||||
if (!wallet) {
|
||||
throw runtime_error("Wallet is not initialized yet");
|
||||
}
|
||||
|
||||
bool ready;
|
||||
if (!wallet->multisig(&ready)) {
|
||||
throw runtime_error("Wallet is not multisig");
|
||||
}
|
||||
|
||||
if (!ready) {
|
||||
throw runtime_error("Multisig wallet is not finalized yet");
|
||||
}
|
||||
}
|
||||
|
||||
void checkMultisigWalletNotReady(const tools::wallet2* wallet) {
|
||||
if (!wallet) {
|
||||
throw runtime_error("Wallet is not initialized yet");
|
||||
}
|
||||
|
||||
bool ready;
|
||||
if (!wallet->multisig(&ready)) {
|
||||
throw runtime_error("Wallet is not multisig");
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
throw runtime_error("Multisig wallet is already finalized");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Wallet2CallbackImpl : public tools::i_wallet2_callback
|
||||
@@ -1058,6 +1088,132 @@ void WalletImpl::setSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex
|
||||
}
|
||||
}
|
||||
|
||||
MultisigState WalletImpl::multisig() const {
|
||||
MultisigState state;
|
||||
state.isMultisig = m_wallet->multisig(&state.isReady, &state.threshold, &state.total);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
string WalletImpl::getMultisigInfo() const {
|
||||
try {
|
||||
clearStatus();
|
||||
return m_wallet->get_multisig_info();
|
||||
} catch (const exception& e) {
|
||||
LOG_ERROR("Error on generating multisig info: ") << e.what();
|
||||
setStatusError(string(tr("Failed to get multisig info: ")) + e.what());
|
||||
}
|
||||
|
||||
return string();
|
||||
}
|
||||
|
||||
string WalletImpl::makeMultisig(const vector<string>& info, uint32_t threshold) {
|
||||
try {
|
||||
clearStatus();
|
||||
|
||||
if (m_wallet->multisig()) {
|
||||
throw runtime_error("Wallet is already multisig");
|
||||
}
|
||||
|
||||
return m_wallet->make_multisig(epee::wipeable_string(m_password), info, threshold);
|
||||
} catch (const exception& e) {
|
||||
LOG_ERROR("Error on making multisig wallet: ") << e.what();
|
||||
setStatusError(string(tr("Failed to make multisig: ")) + e.what());
|
||||
}
|
||||
|
||||
return string();
|
||||
}
|
||||
|
||||
bool WalletImpl::finalizeMultisig(const vector<string>& extraMultisigInfo) {
|
||||
try {
|
||||
clearStatus();
|
||||
checkMultisigWalletNotReady(m_wallet);
|
||||
|
||||
if (m_wallet->finalize_multisig(epee::wipeable_string(m_password), extraMultisigInfo)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
setStatusError(tr("Failed to finalize multisig wallet creation"));
|
||||
} catch (const exception& e) {
|
||||
LOG_ERROR("Error on finalizing multisig wallet creation: ") << e.what();
|
||||
setStatusError(string(tr("Failed to finalize multisig wallet creation: ")) + e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WalletImpl::exportMultisigImages(string& images) {
|
||||
try {
|
||||
clearStatus();
|
||||
checkMultisigWalletReady(m_wallet);
|
||||
|
||||
auto blob = m_wallet->export_multisig();
|
||||
images = epee::string_tools::buff_to_hex_nodelimer(blob);
|
||||
return true;
|
||||
} catch (const exception& e) {
|
||||
LOG_ERROR("Error on exporting multisig images: ") << e.what();
|
||||
setStatusError(string(tr("Failed to export multisig images: ")) + e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t WalletImpl::importMultisigImages(const vector<string>& images) {
|
||||
try {
|
||||
clearStatus();
|
||||
checkMultisigWalletReady(m_wallet);
|
||||
|
||||
std::vector<std::string> blobs;
|
||||
blobs.reserve(images.size());
|
||||
|
||||
for (const auto& image: images) {
|
||||
std::string blob;
|
||||
if (!epee::string_tools::parse_hexstr_to_binbuff(image, blob)) {
|
||||
LOG_ERROR("Failed to parse imported multisig images");
|
||||
setStatusError(tr("Failed to parse imported multisig images"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
blobs.emplace_back(std::move(blob));
|
||||
}
|
||||
|
||||
return m_wallet->import_multisig(blobs);
|
||||
} catch (const exception& e) {
|
||||
LOG_ERROR("Error on importing multisig images: ") << e.what();
|
||||
setStatusError(string(tr("Failed to import multisig images: ")) + e.what());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signData) {
|
||||
try {
|
||||
clearStatus();
|
||||
checkMultisigWalletReady(m_wallet);
|
||||
|
||||
string binary;
|
||||
if (!epee::string_tools::parse_hexstr_to_binbuff(signData, binary)) {
|
||||
throw runtime_error("Failed to deserialize multisig transaction");
|
||||
}
|
||||
|
||||
tools::wallet2::multisig_tx_set txSet;
|
||||
if (!m_wallet->load_multisig_tx(binary, txSet, {})) {
|
||||
throw runtime_error("couldn't parse multisig transaction data");
|
||||
}
|
||||
|
||||
auto ptx = new PendingTransactionImpl(*this);
|
||||
ptx->m_pending_tx = txSet.m_ptx;
|
||||
ptx->m_signers = txSet.m_signers;
|
||||
|
||||
return ptx;
|
||||
} catch (exception& e) {
|
||||
LOG_ERROR("Error on restoring multisig transaction: ") << e.what();
|
||||
setStatusError(string(tr("Failed to restore multisig transaction: ")) + e.what());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// 1 - properly handle payment id (add another menthod with explicit 'payment_id' param)
|
||||
// 2 - check / design how "Transaction" can be single interface
|
||||
@@ -1095,6 +1251,7 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
std::vector<uint8_t> extra;
|
||||
// if dst_addr is not an integrated address, parse payment_id
|
||||
if (!info.has_payment_id && !payment_id.empty()) {
|
||||
@@ -1155,6 +1312,9 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
|
||||
extra, subaddr_account, subaddr_indices, m_trustedDaemon);
|
||||
}
|
||||
|
||||
if (multisig().isMultisig) {
|
||||
transaction->m_signers = m_wallet->make_multisig_tx_set(transaction->m_pending_tx).m_signers;
|
||||
}
|
||||
} catch (const tools::error::daemon_busy&) {
|
||||
// TODO: make it translatable with "tr"?
|
||||
setStatusError(tr("daemon is busy. Please try again later."));
|
||||
|
||||
Reference in New Issue
Block a user