#include "stdafx.h" using ro::base58; display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : wxPanel(parent, myID_WALLET_UI, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("Wallet")), m_db(nullptr), m_menuitem_add_name(this, &display_wallet::add_name_event_handler) { wxLogMessage(wxT("Loading %s"), walletfile.GetFullPath()); if (!walletfile.IsOk() || !walletfile.HasName() || !walletfile.HasExt()) throw MyException("unexpected file name"); if (!walletfile.FileExists())throw MyException( walletfile.GetFullPath().append(" does not exist.").ToUTF8() ); m_db.reset(Sqlite3_open(walletfile.GetFullPath().ToUTF8())); sql_read_from_misc read_from_misc(m_db); if (!read_from_misc(1) || read_from_misc.value() != WALLET_FILE_IDENTIFIER)throw MyException(sz_unrecognizable_wallet_file_format); if (!read_from_misc(2) || read_from_misc.value() != WALLET_FILE_SCHEMA_VERSION_0_0 || !read_from_misc(4))throw MyException(sz_unrecognized_wallet_schema); read_from_misc.read(m_MasterSecret); if (!m_MasterSecret.valid()) throw MyException(sz_cold_wallets_not_yet_implemented); auto sizer = new wxBoxSizer(wxHORIZONTAL); m_lSizer = new wxBoxSizer(wxVERTICAL); m_rSizer = new wxBoxSizer(wxVERTICAL); sizer->Add(m_lSizer,0, wxGROW, 4); sizer->Add(m_rSizer, 50, wxGROW, 4); SetSizer(sizer); ro::sql read_keys(m_db, R"|(SELECT * FROM "Keys";)|"); sql_read_name read_name(m_db); //*It would be better to have a select statement goes through the name table, in name order. This is unit test code wrongly repurposed. // m_db.reset(nullptr);// Force error of premature destruction of Isqlite3 while (read_keys.step() == Icompiled_sql::ROW) { auto pubkey = read_keys.column(0); auto id = read_keys.column(1); auto use = read_keys.column(2); if (use != 1)throw MyException(sz_unknown_secret_key_algorithm); if (!read_name(id)) throw MyException(sz_no_corresponding_entry); const char* name = read_name.name(); if (m_MasterSecret(name).timesBase() != *pubkey)throw MyException(std::string(sz_public_key_of) + name + sz_fails_to_correspond); m_lSizer->Add( new wxStaticText( this, wxID_ANY, name, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_ELLIPSIZE_END ), 10, wxEXPAND | // make horizontally stretchable wxALL, // and make border all around 2); m_rSizer->Add( new wxStaticText( this, wxID_ANY, "#" + base58(*pubkey).operator std::string(), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END ), 10, wxEXPAND | // make horizontally stretchable wxALL, // and make border all around 2); } Bind(wxEVT_CLOSE_WINDOW, &display_wallet::OnClose, this); this->SetSize(this->GetParent()->GetClientSize()); singletonFrame->m_LastUsedSqlite.Assign(walletfile); wxMenu* menuFile{ singletonFrame->GetMenuBar()->GetMenu(0) }; singletonFrame->GetMenuBar()->EnableTop(1, true); //enable edit menu. wxMenu* menuEdit{ singletonFrame->GetMenuBar()->GetMenu(1) }; m_menuitem_add_name.Insert(menuEdit, 0, "add name", "create new Zooko identity"); } display_wallet::~display_wallet() { assert(true); singletonFrame->GetMenuBar()->EnableTop(1, false); //disable edit menu. } void display_wallet::close_menu_event_handler(wxCommandEvent& event) { Close(true); } void display_wallet::add_name_event_handler(wxCommandEvent& event) { wxTextEntryDialog dialog(this, R"("A Zooko name has a human readable name, and a public key defined by the name and the wallet master secret)", "Create a Zooko name", "", wxOK | wxCANCEL); if (dialog.ShowModal() == wxID_OK) { std::string zookoNickname(dialog.GetValue().ToUTF8()); sql_insert_name insert_name(m_db); auto zookoNickname_psz = zookoNickname.c_str(); insert_name( zookoNickname_psz, m_MasterSecret(zookoNickname_psz).timesBase() ); } } void display_wallet::OnClose(wxCloseEvent& event) { // This event gives you the opportunity to clean up anything that needs explicit cleanup, albeit if you have done your work right nothing should need explicit cleanup, // and to object to the closing in a "file not saved" type situation. // https://docs.wxwidgets.org/trunk/classwx_close_event.html DestroyChildren(); Destroy(); //Default handler will destroy the window. This is our handler for the user calling close, // replacing the default handler.' if (singletonFrame->m_panel ==this)singletonFrame->m_panel = nullptr; }