@@ -960,13 +960,32 @@ PYBIND11_MODULE(monero, m) {
960960 MONERO_CATCH_AND_RETHROW (monero::monero_transfer_query::deserialize_from_block (transfer_query_json));
961961 }, py::arg (" transfer_query_json" ))
962962 .def_readwrite (" incoming" , &monero::monero_transfer_query::m_is_incoming)
963+ .def_property (" outgoing" ,
964+ [](const monero::monero_transfer_query& self) { return self.is_outgoing (); },
965+ [](monero::monero_transfer_query& self, const boost::optional<bool >& val) {
966+ if (val == boost::none) self.m_is_incoming = boost::none;
967+ else self.m_is_incoming = !val.get ();
968+ })
963969 .def_readwrite (" address" , &monero::monero_transfer_query::m_address)
964970 .def_readwrite (" addresses" , &monero::monero_transfer_query::m_addresses)
965- .def_readwrite (" address " , &monero::monero_transfer_query::m_subaddress_index)
971+ .def_readwrite (" subaddress_index " , &monero::monero_transfer_query::m_subaddress_index)
966972 .def_readwrite (" subaddress_indices" , &monero::monero_transfer_query::m_subaddress_indices)
967973 .def_readwrite (" destinations" , &monero::monero_transfer_query::m_destinations)
968974 .def_readwrite (" has_destinations" , &monero::monero_transfer_query::m_has_destinations)
969- .def_readwrite (" tx_query" , &monero::monero_transfer_query::m_tx_query)
975+ .def_property (" tx_query" ,
976+ [](const monero::monero_transfer_query& self) { return self.m_tx_query ; },
977+ [](std::shared_ptr<monero::monero_transfer_query>& self, const std::shared_ptr<monero::monero_tx_query>& val) {
978+ const auto old_query = self->m_tx_query ;
979+ self->m_tx_query = val;
980+ if (val != nullptr ) {
981+ val->m_transfer_query = self;
982+ }
983+ else self->m_tx_query = boost::none;
984+
985+ if (old_query != boost::none) {
986+ old_query.get ()->m_transfer_query = boost::none;
987+ }
988+ })
970989 .def (" copy" , [](const std::shared_ptr<monero::monero_transfer_query>& self) {
971990 auto tgt = std::make_shared<monero::monero_transfer_query>();
972991 MONERO_CATCH_AND_RETHROW (self->copy (self, tgt));
@@ -1003,7 +1022,21 @@ PYBIND11_MODULE(monero, m) {
10031022 .def_readwrite (" subaddress_indices" , &monero::monero_output_query::m_subaddress_indices)
10041023 .def_readwrite (" min_amount" , &monero::monero_output_query::m_min_amount)
10051024 .def_readwrite (" max_amount" , &monero::monero_output_query::m_max_amount)
1006- .def_readwrite (" tx_query" , &monero::monero_output_query::m_tx_query)
1025+ .def_readonly (" tx_query" , &monero::monero_output_query::m_tx_query)
1026+ .def (" set_tx_query" , [](const std::shared_ptr<monero::monero_output_query>& self, const std::shared_ptr<monero::monero_tx_query>& val, bool output_query) {
1027+ const auto old_query = self->m_tx_query ;
1028+ if (val != nullptr ) {
1029+ self->m_tx_query = val;
1030+ if (output_query) val->m_output_query = self;
1031+ else val->m_input_query = self;
1032+ } else {
1033+ self->m_tx_query = boost::none;
1034+ }
1035+ if (old_query != boost::none) {
1036+ if (output_query) old_query.get ()->m_output_query = boost::none;
1037+ else old_query.get ()->m_input_query = boost::none;
1038+ }
1039+ }, py::arg (" tx_query" ), py::arg (" output_query" ))
10071040 .def (" copy" , [](const std::shared_ptr<monero::monero_output_query>& self) {
10081041 auto tgt = std::make_shared<monero::monero_output_query>();
10091042 MONERO_CATCH_AND_RETHROW (self->copy (self, tgt));
@@ -1093,9 +1126,51 @@ PYBIND11_MODULE(monero, m) {
10931126 .def_readwrite (" min_height" , &monero::monero_tx_query::m_min_height)
10941127 .def_readwrite (" max_height" , &monero::monero_tx_query::m_max_height)
10951128 .def_readwrite (" include_outputs" , &monero::monero_tx_query::m_include_outputs)
1096- .def_readwrite (" transfer_query" , &monero::monero_tx_query::m_transfer_query)
1097- .def_readwrite (" input_query" , &monero::monero_tx_query::m_input_query)
1098- .def_readwrite (" output_query" , &monero::monero_tx_query::m_output_query)
1129+ .def_property (" transfer_query" ,
1130+ [](const monero::monero_tx_query& self) { return self.m_transfer_query ; },
1131+ [](std::shared_ptr<monero::monero_tx_query>& self, const boost::optional<std::shared_ptr<monero::monero_transfer_query>>& val) {
1132+ const auto old_query = self->m_transfer_query ;
1133+ self->m_transfer_query = val;
1134+ if (self->m_transfer_query != boost::none) {
1135+ self->m_transfer_query .get ()->m_tx_query = self;
1136+ }
1137+ if (old_query != boost::none) {
1138+ if (val != boost::none && val.get () == old_query.get ()) {
1139+ return ;
1140+ }
1141+ old_query.get ()->m_tx_query = boost::none;
1142+ }
1143+ })
1144+ .def_property (" input_query" ,
1145+ [](const monero::monero_tx_query& self) { return self.m_input_query ; },
1146+ [](std::shared_ptr<monero::monero_tx_query>& self, const boost::optional<std::shared_ptr<monero::monero_output_query>>& val) {
1147+ const auto old_query = self->m_input_query ;
1148+ self->m_input_query = val;
1149+ if (self->m_input_query != boost::none) {
1150+ self->m_input_query .get ()->m_tx_query = self;
1151+ }
1152+ if (old_query != boost::none) {
1153+ if (val != boost::none && val.get () == old_query.get ()) {
1154+ return ;
1155+ }
1156+ old_query.get ()->m_tx_query = boost::none;
1157+ }
1158+ })
1159+ .def_property (" output_query" ,
1160+ [](const monero::monero_tx_query& self) { return self.m_output_query ; },
1161+ [](std::shared_ptr<monero::monero_tx_query>& self, const boost::optional<std::shared_ptr<monero::monero_output_query>>& val) {
1162+ const auto old_query = self->m_output_query ;
1163+ self->m_output_query = val;
1164+ if (self->m_output_query != boost::none) {
1165+ self->m_output_query .get ()->m_tx_query = self;
1166+ }
1167+ if (old_query != boost::none) {
1168+ if (val != boost::none && val.get () == old_query.get ()) {
1169+ return ;
1170+ }
1171+ old_query.get ()->m_tx_query = boost::none;
1172+ }
1173+ })
10991174 .def (" copy" , [](const std::shared_ptr<monero::monero_tx_query>& self) {
11001175 auto tgt = std::make_shared<monero::monero_tx_query>();
11011176 MONERO_CATCH_AND_RETHROW (self->copy (self, tgt));
@@ -1686,6 +1761,16 @@ PYBIND11_MODULE(monero, m) {
16861761 .def (" set_subaddress_label" , [](PyMoneroWallet& self, uint32_t account_idx, uint32_t subaddress_idx, const std::string& label) {
16871762 MONERO_CATCH_AND_RETHROW (self.set_subaddress_label (account_idx, subaddress_idx, label));
16881763 }, py::arg (" account_idx" ), py::arg (" subaddress_idx" ), py::arg (" label" ) = " " )
1764+ .def (" get_tx" , [](PyMoneroWallet& self, const std::string& tx_hash) {
1765+ std::shared_ptr<monero::monero_tx_wallet> result = nullptr ;
1766+ monero_tx_query query;
1767+ query.m_hashes .push_back (tx_hash);
1768+ auto txs = self.get_txs (query);
1769+ if (txs.size () > 0 ) {
1770+ result = txs[0 ];
1771+ }
1772+ return result;
1773+ }, py::arg (" tx_hash" ))
16891774 .def (" get_txs" , [](PyMoneroWallet& self) {
16901775 MONERO_CATCH_AND_RETHROW (self.get_txs ());
16911776 })
@@ -1703,6 +1788,22 @@ PYBIND11_MODULE(monero, m) {
17031788 throw PyMoneroError (e.what ());
17041789 }
17051790 }, py::arg (" query" ))
1791+ .def (" get_txs" , [](PyMoneroWallet& self, const std::vector<std::string>& tx_hashes) {
1792+ try {
1793+ monero_tx_query query;
1794+ query.m_hashes = tx_hashes;
1795+ auto txs = self.get_txs (query);
1796+ PyMoneroUtils::sort_txs_wallet (txs, query.m_hashes );
1797+ return txs;
1798+ } catch (const PyMoneroRpcError& e) {
1799+ throw ;
1800+ } catch (const PyMoneroError& e) {
1801+ throw ;
1802+ }
1803+ catch (const std::exception& e) {
1804+ throw PyMoneroError (e.what ());
1805+ }
1806+ }, py::arg (" tx_hashes" ))
17061807 .def (" get_transfers" , [](PyMoneroWallet& self, const monero::monero_transfer_query& query) {
17071808 MONERO_CATCH_AND_RETHROW (self.get_transfers (query));
17081809 }, py::arg (" query" ))
@@ -1776,7 +1877,12 @@ PYBIND11_MODULE(monero, m) {
17761877 MONERO_CATCH_AND_RETHROW (self.sign_message (msg, signature_type, account_idx, subaddress_idx));
17771878 }, py::arg (" msg" ), py::arg (" signature_type" ), py::arg (" account_idx" ) = 0 , py::arg (" subaddress_idx" ) = 0 )
17781879 .def (" verify_message" , [](PyMoneroWallet& self, const std::string& msg, const std::string& address, const std::string& signature) {
1779- MONERO_CATCH_AND_RETHROW (self.verify_message (msg, address, signature));
1880+ try {
1881+ return self.verify_message (msg, address, signature);
1882+ } catch (...) {
1883+ // TODO wallet full can differentiate incorrect from invalid address, but rpc returns -2 for both, so returning bad result for consistency
1884+ return monero::monero_message_signature_result ();
1885+ }
17801886 }, py::arg (" msg" ), py::arg (" address" ), py::arg (" signature" ))
17811887 .def (" get_tx_key" , [](PyMoneroWallet& self, const std::string& tx_hash) {
17821888 MONERO_CATCH_AND_RETHROW (self.get_tx_key (tx_hash));
0 commit comments