Skip to content

configure.ac: autodetect OSX SDK path#647

Open
jameshilliard wants to merge 1 commit into
goatpig:devfrom
jameshilliard:isysroot
Open

configure.ac: autodetect OSX SDK path#647
jameshilliard wants to merge 1 commit into
goatpig:devfrom
jameshilliard:isysroot

Conversation

@jameshilliard
Copy link
Copy Markdown

Fixes:

Undefined symbols for architecture x86_64:
  "___darwin_check_fd_set_overflow", referenced from:
      _select_add in libevent.a(select.o)
      _select_del in libevent.a(select.o)
      _select_dispatch in libevent.a(select.o)
      _uv__stream_osx_select in libuv.a(libuv_la-stream.o)

Fixes:
Undefined symbols for architecture x86_64:
  "___darwin_check_fd_set_overflow", referenced from:
      _select_add in libevent.a(select.o)
      _select_del in libevent.a(select.o)
      _select_dispatch in libevent.a(select.o)
      _uv__stream_osx_select in libuv.a(libuv_la-stream.o)
@goatpig
Copy link
Copy Markdown
Owner

goatpig commented Dec 7, 2020

What is using libevent besides LWS? Is it dynamically linked on OSX? This is looking for the static lib too.

@jameshilliard
Copy link
Copy Markdown
Author

Well this is really just an issue with the sdk path being needed in order for the compiler to properly handle certain symbols, it's not really specific to libevent or LWS.

@goatpig
Copy link
Copy Markdown
Owner

goatpig commented Dec 7, 2020

Ok, will merge once im done with the current refactoring of the cli arg handler.

@ezzmido027-create
Copy link
Copy Markdown

http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html# ===========================================================================## SYNOPSIS@@ -10,13 +10,13 @@## Check for baseline language coverage in the compiler for the specified# version of the C++ standard. If necessary, add switches to CXX and# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)# or '14' (for the C++14 standard).# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for# the respective C++ standard version.## The second argument, if specified, indicates whether you insist on an# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.# -std=c++11). If neither is specified, you get whatever works, with# preference for an extended mode.# preference for no added switch, and then for an extended mode.## The third argument, if specified 'mandatory' or if left unspecified,# indicates that baseline support for the specified C++ standard is@@ -33,21 +33,26 @@# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov sokolov@google.com# Copyright (c) 2015 Paul Norman penorman@mac.com# Copyright (c) 2015 Moritz Klammler moritz@klammler.eu# Copyright (c) 2016, 2018 Krzesimir Nowak qdlacz@gmail.com# Copyright (c) 2019 Enji Cooper yaneurabeya@gmail.com# Copyright (c) 2020 Jason Merrill jason@redhat.com# Copyright (c) 2021 Jörn Heusipp osmanx@problemloesungsmaschine.de## Copying and distribution of this file, with or without modification, are# permitted in any medium without royalty provided the copyright notice# and this notice are preserved. This file is offered as-is, without any# warranty.#serial 4#serial 18dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macrodnl (serial version number 13).AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [], [$1], [14], [], [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [$1], [20], [ax_cxx_compile_alternatives="20"], [m4_fatal([invalid first argument $1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [],@@ -57,26 +62,23 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument $3' to AX_CXX_COMPILE_STDCXX])]) m4_if([$4], [], [ax_cxx_compile_cxx$1_try_default=true], [$4], [default], [ax_cxx_compile_cxx$1_try_default=true], [$4], [nodefault], [ax_cxx_compile_cxx$1_try_default=false], [m4_fatal([invalid fourth argument $4' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no m4_if([$4], [nodefault], [], [dnl AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [ax_cv_cxx_compile_cxx$1=yes], [ax_cv_cxx_compile_cxx$1=no])]) if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ac_success=yes fi]) m4_if([$2], [], [dnl AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [ax_cv_cxx_compile_cxx$1=yes], [ax_cv_cxx_compile_cxx$1=no])]) if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ac_success=yes fi]) m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then for switch in -std=gnu++$1 -std=gnu++0x; do for alternative in ${ax_cxx_compile_alternatives}; do switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar,@@ -102,22 +104,36 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then dnl AS_TR_SH maps both :and=to` so -std:c++17 would collide dnl with -std=c++17. We suffix the cache variable name with MSVC to dnl avoid this. switch=-std:c++${alternative} cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1${switch}MSVC]) else cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1$switch]) fi ac_success=yes AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([AX_CXX_COMPILE_STDCXX_testbody$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done@@ -146,14 +162,30 @@ m4_define([AX_CXX_COMPILE_STDCXX_testbody_11], AX_CXX_COMPILE_STDCXX_testbody_new_in_11)dnl Test body for checking C++14 supportm4_define([AX_CXX_COMPILE_STDCXX_testbody_14], AX_CXX_COMPILE_STDCXX_testbody_new_in_11 AX_CXX_COMPILE_STDCXX_testbody_new_in_14)dnl Test body for checking C++17 supportm4_define([AX_CXX_COMPILE_STDCXX_testbody_17], AX_CXX_COMPILE_STDCXX_testbody_new_in_11 AX_CXX_COMPILE_STDCXX_testbody_new_in_14 AX_CXX_COMPILE_STDCXX_testbody_new_in_17)dnl Test body for checking C++20 supportm4_define([AX_CXX_COMPILE_STDCXX_testbody_20], AX_CXX_COMPILE_STDCXX_testbody_new_in_11 AX_CXX_COMPILE_STDCXX_testbody_new_in_14 AX_CXX_COMPILE_STDCXX_testbody_new_in_17 AX_CXX_COMPILE_STDCXX_testbody_new_in_20)dnl Tests for new features in C++11@@ -166,7 +198,11 @@ m4_define([AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[#error "This is not a C++ compiler"#elif cplusplus < 201103L// MSVC always sets cplusplus to 199711L in older versions; newer versions// only set it correctly if /Zc:cplusplus is specified as well as a// /std:c++NN switch:// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-cplusplus/#elif cplusplus < 201103L && !defined MSC_VER#error "This is not a C++11 compiler"@@ -191,11 +227,13 @@ namespace cxx11 struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} };@@ -396,13 +434,13 @@ namespace cxx11 template <int N0, int... N1toN> struct sum<N0, N1toN...> { static const int value = N0 + sum<N1toN...>::value; static constexpr auto value = N0 + sum<N1toN...>::value; }; template <> struct sum<> { static const int value = 0; static constexpr auto value = 0; }; static_assert(sum<>::value == 0, "");@@ -455,7 +493,7 @@ m4_define([AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[#error "This is not a C++ compiler"#elif cplusplus < 201402L#elif cplusplus < 201402L && !defined MSC_VER#error "This is not a C++14 compiler"@@ -524,7 +562,7 @@ namespace cxx14 } namespace test_digit_seperators namespace test_digit_separators { constexpr auto ten_million = 100'000'000;@@ -566,3 +604,415 @@ namespace cxx14#endif // cplusplus >= 201402L]])dnl Tests for new features in C++17m4_define([AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[// If the compiler admits that it is not ready for C++17, why torture it?// Hopefully, this will speed up the test.#ifndef cplusplus#error "This is not a C++ compiler"#elif cplusplus < 201703L && !defined MSC_VER#error "This is not a C++17 compiler"#else#include <initializer_list>#include #include <type_traits>namespace cxx17{ namespace test_constexpr_lambdas { constexpr int foo = {return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template<typename... Args> int multiply(Args... args) { return (args * ... * 1); } template<typename... Args> bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same<std::initializer_list, decltype(foo)>::value); static_assert(std::is_same<int, decltype(bar)>::value); } namespace test_typename_in_template_template_parameter { template<template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return *this { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template <typename T1, typename T2> struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair<int, int> pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair<int, int>& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T, T*); template<typename T1, typename T2> Good f(T1*, T2*); static_assert (std::is_same_v<Good, decltype(f(g1, g2))>); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } }} // namespace cxx17#endif // cplusplus < 201703L && !defined MSC_VER]])dnl Tests for new features in C++20m4_define([AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[#ifndef cplusplus#error "This is not a C++ compiler"#elif cplusplus < 202002L && !defined MSC_VER#error "This is not a C++20 compiler"#else#include namespace cxx20{// As C++20 supports feature test macros in the standard, there is no// immediate need to actually test for feature availability on the// Autoconf side.} // namespace cxx20#endif // cplusplus < 202002L && !defined MSC_VER]])Collapse file‎build-aux/m4/ax_cxx_compile_stdcxx_17.m4‎Copy file name to clipboard+35Lines changed: 35 additions & 0 deletionsOriginal file line numberDiff line numberDiff line change@@ -0,0 +1,35 @@# =============================================================================# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_17.html# =============================================================================## SYNOPSIS## AX_CXX_COMPILE_STDCXX_17([ext|noext], [mandatory|optional])## DESCRIPTION## Check for baseline language coverage in the compiler for the C++17# standard; if necessary, add switches to CXX and CXXCPP to enable# support.## This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX# macro with the version set to C++17. The two optional arguments are# forwarded literally as the second and third argument respectively.# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for# more information. If you want to use this macro, you also need to# download the ax_cxx_compile_stdcxx.m4 file.## LICENSE## Copyright (c) 2015 Moritz Klammler moritz@klammler.eu# Copyright (c) 2016 Krzesimir Nowak qdlacz@gmail.com## Copying and distribution of this file, with or without modification, are# permitted in any medium without royalty provided the copyright notice# and this notice are preserved. This file is offered as-is, without any# warranty.#serial 2AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX])AC_DEFUN([AX_CXX_COMPILE_STDCXX_17], [AX_CXX_COMPILE_STDCXX([17], [$1], [$2])])Collapse file‎configure.ac‎Copy file name to clipboardExpand all lines: configure.ac+2-2Lines changed: 2 additions & 2 deletionsOriginal file line numberDiff line numberDiff line change@@ -80,8 +80,8 @@ AC_CONFIG_MACRO_DIR([build-aux/m4])m4_include([build-aux/m4/ax_check_compile_flag.m4])m4_include([build-aux/m4/ax_cxx_compile_stdcxx.m4])#check for c++14AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory], [nodefault])#check for c++17AX_CXX_COMPILE_STDCXX_17([noext], [mandatory])# Make the compilation flags quiet unless V=1 is used.m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])Collapse file‎cppForSwig/BinaryData.h‎Copy file name to clipboardExpand all lines: cppForSwig/BinaryData.h+2-4Lines changed: 2 additions & 4 deletionsOriginal file line numberDiff line numberDiff line change@@ -108,7 +108,7 @@ class BinaryData ///////////////////////////////////////////////////////////////////////////// BinaryData(void) : data(0) { } explicit BinaryData(size_t sz) { alloc(sz); } BinaryData(uint8_t const * inData, size_t sz) BinaryData(uint8_t const * inData, size_t sz) { copyFrom(inData, sz); } BinaryData(char const * inData, size_t sz) { copyFrom(inData, sz); } BinaryData(uint8_t const * dstart, uint8_t const * dend )@@ -561,16 +561,14 @@ class BinaryData std::vector<uint8_t> data;private: void alloc(size_t sz) void alloc(size_t sz) { if(sz != getSize()) { data.clear(); data.resize(sz); } }};Collapse file‎cppForSwig/BridgeAPI/CppBridge.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/BridgeAPI/CppBridge.cpp+47-14Lines changed: 47 additions & 14 deletionsOriginal file line numberDiff line numberDiff line change@@ -271,7 +271,7 @@ void CppBridge::createBackupStringForWallet(const string& waaId, }); auto lbd = passPromptObj->getLambda(); Armory::Seeds::WalletBackup backupData; unique_ptrArmory::Seeds::WalletBackup backupData = nullptr; try { //grab wallet@@ -290,33 +290,66 @@ void CppBridge::createBackupStringForWallet(const string& waaId, auto reply = payload->mutable_reply(); reply->set_reference_id(msgId); if (backupData.rootClear.empty()) if (backupData == nullptr) { //return on error reply->set_success(false); writeToClient(move(payload)); return; } auto backupStringProto = reply->mutable_wallet()->mutable_backup_string(); for (auto& line : backupData.rootClear) backupStringProto->add_root_clear(line); auto backupE16 = dynamic_castArmory::Seeds::Backup_Easy16*( backupData.get()); if (backupE16 == nullptr) { throw runtime_error("[createBackupStringForWallet]" " invalid backup type"); } for (auto& line : backupData.rootEncr) backupStringProto->add_root_encr(line); auto backupStringProto = reply->mutable_wallet()->mutable_backup_string(); if (!backupData.chaincodeClear.empty()) //cleartext root { for (auto& line : backupData.chaincodeClear) backupStringProto->add_chain_clear(line); auto line1 = backupE16->getRoot( Armory::Seeds::Backup_Easy16::LineIndex::One, false); backupStringProto->add_root_clear(line1.data(), line1.size()); auto line2 = backupE16->getRoot( Armory::Seeds::Backup_Easy16::LineIndex::Two, false); backupStringProto->add_root_clear(line2.data(), line2.size()); //encrypted root auto line3 = backupE16->getRoot( Armory::Seeds::Backup_Easy16::LineIndex::One, true); backupStringProto->add_root_encr(line3.data(), line3.size()); auto line4 = backupE16->getRoot( Armory::Seeds::Backup_Easy16::LineIndex::Two, true); backupStringProto->add_root_encr(line3.data(), line3.size()); } for (auto& line : backupData.chaincodeEncr) backupStringProto->add_chain_encr(line); if (backupE16->hasChaincode()) { //cleartext chaincode auto line1 = backupE16->getChaincode( Armory::Seeds::Backup_Easy16::LineIndex::One, false); backupStringProto->add_chain_clear(line1.data(), line1.size()); auto line2 = backupE16->getChaincode( Armory::Seeds::Backup_Easy16::LineIndex::Two, false); backupStringProto->add_chain_clear(line2.data(), line2.size()); //encrypted chaincode auto line3 = backupE16->getChaincode( Armory::Seeds::Backup_Easy16::LineIndex::One, true); backupStringProto->add_chain_encr(line3.data(), line3.size()); auto line4 = backupE16->getChaincode( Armory::Seeds::Backup_Easy16::LineIndex::Two, true); backupStringProto->add_chain_encr(line4.data(), line4.size()); } //secure print passphrase backupStringProto->set_sp_pass( backupData.spPass.toCharPtr(), backupData.spPass.getSize()); auto spPass = backupE16->getSpPass(); backupStringProto->set_sp_pass(spPass.data(), spPass.size()); reply->set_success(true); writeToClient(move(payload));Collapse file‎cppForSwig/BridgeAPI/WalletManager.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/BridgeAPI/WalletManager.cpp+14-7Lines changed: 14 additions & 7 deletionsOriginal file line numberDiff line numberDiff line change@@ -1,6 +1,6 @@////////////////////////////////////////////////////////////////////////////////// //// Copyright (C) 2016-20, goatpig //// Copyright (C) 2016-2023, goatpig //// Distributed under the MIT license //// See LICENSE-MIT or https://opensource.org/licenses/MIT //// //@@ -9,6 +9,7 @@#include "WalletManager.h"#include "Wallets/Seeds/Backups.h"#include "PassphrasePrompt.h"#include "../Wallets/Seeds/Seeds.h"#ifdef WIN32#include "leveldb_windows_port\win32_posix\dirent_win32.h"@@ -20,6 +21,7 @@ using namespace std;using namespace Armory::Signer;using namespace Armory::Accounts;using namespace Armory::Wallets;using namespace Armory::Seeds;#define WALLET_135_HEADER "\xbaWALLET\x00"#define PYBTC_ADDRESS_SIZE 237@@ -151,8 +153,11 @@ shared_ptr WalletManager::createNewWallet( if (extraEntropy.getSize() >= 32) root.XOR(extraEntropy); auto wallet = AssetWallet_Single::createFromPrivateRoot_Armory135( path, root, {}, pass, controlPass, lookup); unique_ptr seed(new ClearTextSeed_Armory135(root, ClearTextSeed_Armory135::LegacyType::Armory200)); auto wallet = AssetWallet_Single::createFromSeed(move(seed), pass, controlPass, path, lookup); return addWallet(wallet, wallet->getMainAccountID());}@@ -635,7 +640,7 @@ map<BinaryData, shared_ptr> WalletContainer::getUpdatedAddressMap(}////////////////////////////////////////////////////////////////////////////////Armory::Seeds::WalletBackup WalletContainer::getBackupStrings(unique_ptrArmory::Seeds::WalletBackup WalletContainer::getBackupStrings( const PassphraseLambda& passLbd) const{ auto wltSingle = dynamic_pointer_cast<AssetWallet_Single>(wallet);@@ -932,9 +937,11 @@ shared_ptr<AssetWallet_Single> Armory135Header::migrate( } else { wallet = AssetWallet_Single::createFromPrivateRoot_Armory135( folder, decryptedRoot, chaincodeCopy, privKeyPass, controlPass, highestIndex); unique_ptr seed(new ClearTextSeed_Armory135( decryptedRoot, chaincodeCopy)); wallet = AssetWallet_Single::createFromSeed(move(seed), privKeyPass, controlPass, folder, highestIndex); } //main account id, check it matches armory wallet idCollapse file‎cppForSwig/BridgeAPI/WalletManager.h‎Copy file name to clipboardExpand all lines: cppForSwig/BridgeAPI/WalletManager.h+2-1Lines changed: 2 additions & 1 deletionOriginal file line numberDiff line numberDiff line change@@ -215,7 +215,8 @@ class WalletContainer Armory::Wallets::AssetKeyType getHighestUsedIndex(void) const; std::map<BinaryData, std::shared_ptr> getUpdatedAddressMap(); Armory::Seeds::WalletBackup getBackupStrings(const PassphraseLambda&) const; std::unique_ptrArmory::Seeds::WalletBackup getBackupStrings( const PassphraseLambda&) const; void setComment(const std::string&, const std::string&); void setLabels(const std::string&, const std::string&);Collapse file‎cppForSwig/SecureBinaryData.h‎Copy file name to clipboardExpand all lines: cppForSwig/SecureBinaryData.h+11-1Lines changed: 11 additions & 1 deletionOriginal file line numberDiff line numberDiff line change@@ -148,7 +148,17 @@ class SecureBinaryData : public BinaryData return {}; SecureBinaryData sbd(str.size()); memcpy(sbd.getPtr(), str.c_str(), str.size()); memcpy(sbd.getPtr(), str.data(), str.size()); return sbd; } static SecureBinaryData fromStringView(const std::string_view& strv) { if (strv.empty()) return {}; SecureBinaryData sbd(strv.size()); memcpy(sbd.getPtr(), strv.data(), strv.size()); return sbd; }};Collapse file‎cppForSwig/Signer/ResolverFeed.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Signer/ResolverFeed.cpp+3-1Lines changed: 3 additions & 1 deletionOriginal file line numberDiff line numberDiff line change@@ -42,7 +42,9 @@ uint32_t BIP32_PublicDerivedRoot::getThisFingerprint() const if (thisFingerprint == UINT32_MAX) { BIP32_Node node; node.initFromBase58(SecureBinaryData::fromString(xpub)); BinaryDataRef xpubRef; xpubRef.setRef(xpub); node.initFromBase58(xpubRef); thisFingerprint = node.getThisFingerprint(); }Collapse file‎cppForSwig/Wallets/AssetEncryption.h‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/AssetEncryption.h-1Lines changed: 0 additions & 1 deletionOriginal file line numberDiff line numberDiff line change@@ -20,7 +20,6 @@#define PRIVKEY_BYTE 0x82#define ENCRYPTIONKEY_BYTE 0x83#define WALLET_SEED_BYTE 0x84#define CIPHER_DATA_VERSION 0x00000001#define ENCRYPTION_KEY_VERSION 0x00000001Collapse file‎cppForSwig/Wallets/AuthorizedPeers.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/AuthorizedPeers.cpp+6-4Lines changed: 6 additions & 4 deletionsOriginal file line numberDiff line numberDiff line change@@ -14,13 +14,15 @@#include "AuthorizedPeers.h"#include "btc/ecc.h"#include "WalletFileInterface.h"#include "Seeds/Seeds.h"#include "TerminalPassphrasePrompt.h"using namespace std;using namespace Armory::Assets;using namespace Armory::Accounts;using namespace Armory::Wallets;using namespace Armory::Seeds;////////////////////////////////////////////////////////////////////////////////AuthorizedPeers::AuthorizedPeers(@@ -170,10 +172,10 @@ void AuthorizedPeers::createWallet( derPath.push_back(0xF0000000); //generate bip32 node from random seed auto&& seed = CryptoPRNG::generateRandom(32); wallet = AssetWallet_Single::createFromSeed_BIP32_Blank( baseDir, seed, password, controlPassphrase); wallet = AssetWallet_Single::createFromSeed( make_unique<ClearTextSeed_BIP32>( CryptoPRNG::generateRandom(32), SeedType::BIP32_Virgin), password, controlPassphrase, baseDir); auto wltSingle = dynamic_pointer_cast<AssetWallet_Single>(wallet); auto rootBip32 = dynamic_pointer_cast<AssetEntry_BIP32Root>(Collapse file‎cppForSwig/Wallets/BIP32_Node.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/BIP32_Node.cpp+1-1Lines changed: 1 addition & 1 deletionOriginal file line numberDiff line numberDiff line change@@ -120,7 +120,7 @@ void BIP32_Node::initFromSeed(const SecureBinaryData& seed)}////////////////////////////////////////////////////////////////////////////////void BIP32_Node::initFromBase58(const SecureBinaryData& b58)void BIP32_Node::initFromBase58(BinaryDataRef b58){ //sbd doesnt 0 terminate strings as it is not specialized for char strings, //have to set it manually since libbtc b58 code derives string length fromCollapse file‎cppForSwig/Wallets/BIP32_Node.h‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/BIP32_Node.h+1-1Lines changed: 1 addition & 1 deletionOriginal file line numberDiff line numberDiff line change@@ -38,7 +38,7 @@ class BIP32_Node //init void initFromSeed(const SecureBinaryData&); void initFromBase58(const SecureBinaryData&); void initFromBase58(BinaryDataRef); void initFromPrivateKey(uint8_t depth, unsigned leaf_id, unsigned fingerprint, const SecureBinaryData& privKey, const SecureBinaryData& chaincode); void initFromPublicKey(uint8_t depth, unsigned leaf_id, unsigned fingerprint,Collapse file‎cppForSwig/Wallets/DecryptedDataContainer.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/DecryptedDataContainer.cpp+43-10Lines changed: 43 additions & 10 deletionsOriginal file line numberDiff line numberDiff line change@@ -63,11 +63,14 @@ void DecryptedDataContainer::lockOther( shared_ptr other){ if (!ownsLock()) throw DecryptedDataContainerException("unlocked/does not own lock"); { throw DecryptedDataContainerException( "[DecryptedDataContainer::lockOther] unlocked/does not own lock"); } if (lockedDecryptedData == nullptr) throw DecryptedDataContainerException( "nullptr lock! how did we get this far?"); "nullptr lock! how did we get this far?"); otherLocks.push_back(OtherLockedContainer(other));}@@ -103,11 +106,17 @@ unique_ptr DecryptedDataContainer::deriveEncryptionKey({ //sanity check if (!ownsLock()) throw DecryptedDataContainerException("unlocked/does not own lock"); { throw DecryptedDataContainerException( "[DecryptedDataContainer::deriveEncryptionKey]" " unlocked/does not own lock"); } if (lockedDecryptedData == nullptr) { throw DecryptedDataContainerException( "nullptr lock! how did we get this far?"); "nullptr lock! how did we get this far?"); } //does the decryption key have this derivation? auto derivationIter = decrKey->derivedKeys.find(kdfid);@@ -146,7 +155,11 @@ const SecureBinaryData& DecryptedDataContainer::getClearTextAssetData( //sanity check if (!ownsLock()) throw DecryptedDataContainerException("unlocked/does not own lock"); { throw DecryptedDataContainerException( "[DecryptedDataContainer::getClearTextAssetData]" " unlocked/does not own lock"); } if (lockedDecryptedData == nullptr) throw DecryptedDataContainerException(@@ -289,7 +302,11 @@ EncryptionKeyId DecryptedDataContainer::populateEncryptionKey( //sanity check if (!ownsLock()) throw DecryptedDataContainerException("unlocked/does not own lock"); { throw DecryptedDataContainerException( "[DecryptedDataContainer::populateEncryptionKey]" " unlocked/does not own lock"); } if (lockedDecryptedData == nullptr) throw DecryptedDataContainerException(@@ -437,7 +454,11 @@ SecureBinaryData DecryptedDataContainer::encryptData( throw DecryptedDataContainerException("null cipher"); if (!ownsLock()) throw DecryptedDataContainerException("unlocked/does not own lock"); { throw DecryptedDataContainerException( "[DecryptedDataContainer::encryptData]" " unlocked/does not own lock"); } if (lockedDecryptedData == nullptr) throw DecryptedDataContainerException(@@ -573,7 +594,11 @@ void DecryptedDataContainer::deleteFromDisk({ //sanity checks if (!ownsLock()) throw DecryptedDataContainerException("unlocked/does not own lock"); { throw DecryptedDataContainerException( "[DecryptedDataContainer::deleteFromDisk]" " unlocked/does not own lock"); } //erase key, db interface will wipe it from file tx->erase(key);@@ -656,7 +681,11 @@ void DecryptedDataContainer::encryptEncryptionKey( //we have to own the lock on this container before proceeding if (!ownsLock()) throw DecryptedDataContainerException("unlocked/does not own lock"); { throw DecryptedDataContainerException( "[DecryptedDataContainer::encryptEncryptionKey]" " unlocked/does not own lock"); } if (lockedDecryptedData == nullptr) {@@ -790,7 +819,11 @@ void DecryptedDataContainer::eraseEncryptionKey(//we have to own the lock on this container before proceeding if (!ownsLock()) throw DecryptedDataContainerException("unlocked/does not own lock"); { throw DecryptedDataContainerException( "[DecryptedDataContainer::eraseEncryptionKey]" " unlocked/does not own lock"); } if (lockedDecryptedData == nullptr) {Collapse file‎cppForSwig/Wallets/Seeds/Backups.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/Seeds/Backups.cpp+656-367Lines changed: 656 additions & 367 deletions Load DiffLarge diffs are not rendered by default.Collapse file‎cppForSwig/Wallets/Seeds/Backups.h‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/Seeds/Backups.h+139-71Lines changed: 139 additions & 71 deletionsOriginal file line numberDiff line numberDiff line change@@ -11,18 +11,29 @@#include #include #include <string_view>#include "SecureBinaryData.h"#include "EncryptionUtils.h"#include "Wallets.h"#define EASY16_INVALID_CHECKSUM_INDEX UINT8_MAXnamespace BridgeProto{ class RestorePrompt; class RestoreReply;}namespace Armory{ namespace Seeds { //// //forward declarations class ClearTextSeed; class ClearTextSeed_BIP39; ////////////////////////////////////////////////////////////////////////// class RestoreUserException : public std::runtime_error { public:@@ -31,6 +42,7 @@ namespace Armory {} }; //// class Easy16RepairError : public std::runtime_error { public:@@ -40,52 +52,38 @@ namespace Armory }; //// enum BackupType enum class BackupType : int { /* Armory135: For wallets using the Armory specific derivation scheme. / Armory135 = 0, //easy16, seed (2 or 4 lines), hash index is always 0 Armory135 = 0, / BIP32_Seed_Structured: For wallets carrying BIP44/49/84 accounts. Restores to a bip32 wallet with all these accounts. easy16, seed (2 lines), hash index defines seed type: - a: Armory legacy derivation, P2PKH + P2WPK + P2SH-2WPKH addresses in a single address account - b: BIP32 with BIP44/49/84 chains, as individual address accounts - c: BIP32 with no accounts - d: BIP39 seed with BIP44/49/84 chains, as individual address accounts / BIP32_Seed_Structured = 1, Armory200a = 3, Armory200b = 4, Armory200c = 5, Armory200d = 6, / BIP32_Root: For bip32 wallets that do not carry their own seed. Support for this is not implemented at the moment. This type of backup would have to carry the root privkey and chaincode generated through the seed's hmac. //state of an easy16 backup prior to decode Easy16_Unkonwn = 10, May implement support in the future. / BIP32_Root = 2, //bip32 mnemonic phrase (12~24 words), english dictionnary BIP39 = 0xFFFF, / BIP32_Seed_Virgin: No info is provided about the wallet's structure, restores to an empt bip32 wallet. / BIP32_Seed_Virgin = 15, / Default marker value. */ Invalid = UINT32_MAX }; Base58 = 58, //// struct WalletRootData { SecureBinaryData root; SecureBinaryData secondaryData; //raw binary of the seed in hexits, no extra info provided Raw = INT32_MAX - 1, BackupType type; std::string wltId; //end marker Invalid = INT32_MAX }; ////@@ -95,10 +93,14 @@ namespace Armory std::vector repairedIndexes; std::vector checksums; SecureBinaryData data; bool isInitialized(void) const; bool isValid(void) const; int getIndex(void) const; }; //// struct BackupEasy16 struct Easy16Codec { public: /***@@ -111,7 +113,7 @@ namespace Armory one another. ***/ static const std::set<uint8_t> eligibleIndexes; static const std::set eligibleIndexes; private: static BinaryData getHash(const BinaryDataRef&, uint8_t);@@ -120,8 +122,8 @@ namespace Armory public: const static std::vector e16chars; static std::vectorstd::string encode(const BinaryDataRef, uint8_t); static BackupEasy16DecodeResult decode(const std::vectorstd::string&); static std::vector encode(const BinaryDataRef, BackupType); static BackupEasy16DecodeResult decode(const std::vector&); static BackupEasy16DecodeResult decode(const std::vector&); static bool repair(BackupEasy16DecodeResult&); };@@ -144,27 +146,96 @@ namespace Armory SecurePrint(void); std::pair<SecureBinaryData, SecureBinaryData> encrypt( const SecureBinaryData&, const SecureBinaryData&); BinaryDataRef, BinaryDataRef); SecureBinaryData decrypt( const SecureBinaryData&, const BinaryDataRef) const; const SecureBinaryData& getPassphrase(void) const { return passphrase; } }; ////////////////////////////////////////////////////////////////////////// class WalletBackup { friend struct Helpers; protected: const BackupType type; std::string wltId; public: WalletBackup(BackupType); virtual ~WalletBackup(void) = 0; const BackupType& type(void) const; const std::string& getWalletId(void) const; }; //// struct WalletBackup class Backup_Easy16 : public WalletBackup { std::vectorstd::string rootClear; std::vectorstd::string chaincodeClear; friend class Helpers; public: enum class LineIndex : int { One = 0, Two = 1 }; private: std::vector rootClear; std::vector chaincodeClear; std::vectorstd::string rootEncr; std::vectorstd::string chaincodeEncr; std::vector rootEncr; std::vector chaincodeEncr; SecureBinaryData spPass; std::string wltId; public: Backup_Easy16(BackupType); ~Backup_Easy16(void) override; bool hasChaincode(void) const; std::string_view getRoot(LineIndex, bool) const; std::string_view getChaincode(LineIndex, bool) const; std::string_view getSpPass(void) const; static std::unique_ptr<Backup_Easy16> fromLines( const std::vectorstd::string_view&, std::string_view spPass = {}); }; //// class Backup_Base58 : public WalletBackup { private: SecureBinaryData b58String_; public: Backup_Base58(SecureBinaryData); ~Backup_Base58(void) override; std::string_view getBase58String(void) const; static std::unique_ptr<Backup_Base58> fromString( const std::string_view&); }; //// class Backup_BIP39 : public WalletBackup { private: SecureBinaryData mnemonicString_; public: Backup_BIP39(SecureBinaryData); ~Backup_BIP39(void) override; std::string_view getMnemonicString(void) const; static std::unique_ptr<Backup_BIP39> fromMnemonics( const std::vectorstd::string_view&); }; //////// enum RestorePromptType { //invalid backup format@@ -194,34 +265,31 @@ namespace Armory //// struct Helpers { using UserPrompt = std::function<bool( RestorePromptType, const std::vector&, SecureBinaryData&)>; //getting root data from wallets static WalletRootData getRootData( std::shared_ptrWallets::AssetWallet_Single); static WalletRootData getRootData_Multisig( std::shared_ptrWallets::AssetWallet_Multisig); using UserPrompt = std::function<BridgeProto::RestoreReply( BridgeProto::RestorePrompt)>; //backup methods static WalletBackup getWalletBackup( std::shared_ptrWallets::AssetWallet_Single, BackupType bType = BackupType::Invalid); static WalletBackup getWalletBackup( WalletRootData&, static std::unique_ptr getWalletBackup( std::shared_ptrWallets::AssetWallet_Single, BackupType bType = BackupType::Invalid); static std::unique_ptr getWalletBackup( std::unique_ptr, BackupType); static std::unique_ptr getEasy16BackupString( std::unique_ptr); static std::unique_ptr getBIP39BackupString( std::unique_ptr); static std::unique_ptr<Backup_Base58> getBase58BackupString( std::unique_ptr); //restore methods static std::shared_ptrWallets::AssetWallet restoreFromBackup( const std::vectorstd::string&, const BinaryDataRef, const std::string&, const UserPrompt&); static std::shared_ptrWallets::AssetWallet restoreFromBackup( const std::vector&, const BinaryDataRef, const std::string&, const UserPrompt&); std::unique_ptr, const std::string&, const UserPrompt&); static std::unique_ptr restoreFromEasy16( std::unique_ptr, const UserPrompt&, BackupType&); static std::unique_ptr restoreFromBase58( std::unique_ptr); static std::unique_ptr restoreFromBIP39( std::unique_ptr, const UserPrompt&); }; }; //namespace Backups}; //namespace ArmoryCollapse file‎cppForSwig/Wallets/Seeds/Seeds.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/Seeds/Seeds.cpp+602-14Lines changed: 602 additions & 14 deletions Load DiffLarge diffs are not rendered by default.Collapse file‎cppForSwig/Wallets/Seeds/Seeds.h‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/Seeds/Seeds.h+233-8Lines changed: 233 additions & 8 deletionsOriginal file line numberDiff line numberDiff line change@@ -9,32 +9,257 @@#pragma once#include "../AssetEncryption.h"class BIP32_Node;namespace Armory{ namespace Seed namespace Wallets { namespace Encryption { class DecryptedDataContainer; } } /*** Wallet creation diagram *** WalletBackup <---> ClearTextSeed <-------- | | | | v | AssetWallet --> EncryptedSeed / namespace Seeds { ////////////////////////////////////////////////////////////////////////// enum class SeedType : int { / Armory135: For wallets using the legacy Armory derivation scheme. / Armory135 = 0, / BIP32_Structured: For wallets carrying BIP44/49/84 accounts. Restores to a bip32 wallet with all these accounts. / BIP32_Structured = 1, / BIP32_Virgin: No info is provided about the wallet's structure, restores to an empty bip32 wallet. / BIP32_Virgin = 15, / BIP32_base58Root From a base58 of the wallet root. No info about the wallet structure. Cannot be extract as easy16. Mostly used to import HW roots. / BIP32_base58Root = 16, / BIP39: BIP39 seed. Can be outputed as either Easy16 or BIP39 english dictionnary mnemonic. Backup string is always converted into the BIP39 mnemonic then passed through PBKDF2 to generate the seed. Yield a wallet with BIP44, 49 and 84 accounts. / BIP39 = 8, / Raw: Raw entropy. Used for wallet public data encryption and v1 seeds / Raw = INT32_MAX - 1, }; enum class BackupType; ////////////////////////////////////////////////////////////////////////// class ClearTextSeed { private: const SeedType type_; mutable std::string walletId_; mutable std::string masterId_; protected: enum class Prefix : int { Root = 0x11, Chaincode = 0x22, PublicKey = 0x33, RawEntropy = 0x44, Dictionnary = 0x55, LegacyType = 0x66, Base58Root = 0x77 }; virtual std::string computeWalletId(void) const = 0; virtual std::string computeMasterId(void) const = 0; public: ClearTextSeed(SeedType); virtual ~ClearTextSeed(void) = 0; SeedType type(void) const; virtual bool isBackupTypeEligible(BackupType) const = 0; virtual BackupType getPreferedBackupType(void) const = 0; const std::string& getWalletId(void) const; const std::string& getMasterId(void) const; virtual void serialize(BinaryWriter&) const = 0; static std::unique_ptr deserialize( const SecureBinaryData&); }; //////// class ClearTextSeed_Armory135 : public ClearTextSeed { public: enum class LegacyType : int { / Legacy type defines what kinda of backup can be created from this seed. By default, legacy wallets would be created with a Armory200a backup type, which would set the hash index to 3. A wallet restored from an older backup would then yield backups that differ from the old paper. To avoid this, we track which legacy type this seed is from. - seed type of LegacyType::Armory135 will generate BackupType::Armory135 backups - seed type of LegacyType::Armory200 will generate BackupType::Armory200a backups / Armory135 = 12, Armory200 = 34 }; private: const SecureBinaryData root_; const SecureBinaryData chaincode_; const LegacyType legacyType_; protected: std::string computeWalletId(void) const override; std::string computeMasterId(void) const override; public: //will generate random root ClearTextSeed_Armory135(LegacyType lType = LegacyType::Armory200); //root ClearTextSeed_Armory135(const SecureBinaryData&, LegacyType lType = LegacyType::Armory200); //root + chaincode ClearTextSeed_Armory135(const SecureBinaryData&, const SecureBinaryData&, LegacyType lType = LegacyType::Armory135); //overrides ~ClearTextSeed_Armory135(void) override; void serialize(BinaryWriter&) const override; bool isBackupTypeEligible(BackupType) const override; BackupType getPreferedBackupType(void) const override; //local const SecureBinaryData& getRoot(void) const; const SecureBinaryData& getChaincode(void) const; }; //////// class ClearTextSeed_BIP32 : public ClearTextSeed { protected: const SecureBinaryData rawEntropy_; mutable std::shared_ptr<BIP32_Node> rootNode_; protected: std::string computeWalletId(void) const override; std::string computeMasterId(void) const override; public: //seed ClearTextSeed_BIP32(SeedType); ClearTextSeed_BIP32(const SecureBinaryData&, SeedType); BackupType getPreferedBackupType(void) const override; static std::unique_ptr<ClearTextSeed_BIP32> fromBase58( const BinaryDataRef&); //overrides ~ClearTextSeed_BIP32(void) override; virtual void serialize(BinaryWriter&) const override; virtual bool isBackupTypeEligible(BackupType) const override; //locals virtual std::shared_ptr<BIP32_Node> getRootNode(void) const; const SecureBinaryData& getRawEntropy(void) const; }; //////// class ClearTextSeed_BIP39 : public ClearTextSeed_BIP32 { private: const unsigned int dictionnaryId_ = 1; public: ClearTextSeed_BIP39(const SecureBinaryData&, unsigned int); ~ClearTextSeed_BIP39(void) override; void serialize(BinaryWriter&) const override; bool isBackupTypeEligible(BackupType) const override; BackupType getPreferedBackupType(void) const override; std::shared_ptr<BIP32_Node> getRootNode(void) const override; unsigned int getDictionnaryId(void) const; }; ////////////////////////////////////////////////////////////////////////// class EncryptedSeed : public Wallets::Encryption::EncryptedAssetData { / Carries the encrypted ClearTextSeed used to generate the wallet. This class cannot be used to yield wallet seeds on its own, its main purpose is disk IO. Convert to ClearTextSeed for seed/backup manipulations. To convert, feed the decrypted the cipher text to ClearTextSeed::deserialize / private: const SeedType type_; public: using CipherText = std::unique_ptrWallets::Encryption::CipherData; static const Wallets::AssetId seedAssetId_; public: //tors EncryptedSeed( std::unique_ptrWallets::Encryption::CipherData cipher) : Wallets::Encryption::EncryptedAssetData(move(cipher)) {} EncryptedSeed(CipherText, SeedType); ~EncryptedSeed(void) override; //overrides //utils SeedType type(void) const; bool isSame(Wallets::Encryption::EncryptedAssetData const) const override; BinaryData serialize(void) const override; const Wallets::AssetId& getAssetId(void) const override; //static //for disk IO BinaryData serialize(void) const override; static std::unique_ptr deserialize( const BinaryDataRef&); //used at wallet creation static std::unique_ptr fromClearTextSeed( std::unique_ptr, std::unique_ptrWallets::Encryption::Cipher, std::shared_ptrWallets::Encryption::DecryptedDataContainer); }; }} //namespace ArmoryCollapse file‎cppForSwig/Wallets/WalletFileInterface.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/WalletFileInterface.cpp+3-2Lines changed: 3 additions & 2 deletionsOriginal file line numberDiff line numberDiff line change@@ -14,7 +14,7 @@#include "Seeds/Seeds.h"using namespace std;using namespace Armory::Seed;using namespace Armory::Seeds;using namespace Armory::Wallets::IO;using namespace Armory::Wallets::Encryption;@@ -486,7 +486,8 @@ shared_ptr<WalletHeader_Control> WalletDBInterface::setupControlDB( auto cipherCopy = keyStruct.cipher_->getCopy(); auto cipherText = decryptedData->encryptData(cipherCopy.get(), seed); auto cipherData = make_unique(cipherText, move(cipherCopy)); auto encrSeed = make_shared(move(cipherData)); auto encrSeed = make_shared( move(cipherData), SeedType::Raw); //write seed to disk auto&& tx = beginWriteTransaction(CONTROL_DB_NAME);Collapse file‎cppForSwig/Wallets/WalletFileInterface.h‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/WalletFileInterface.h+2-2Lines changed: 2 additions & 2 deletionsOriginal file line numberDiff line numberDiff line change@@ -31,7 +31,7 @@ class PRNG_Fortuna;namespace Armory{ namespace Seed namespace Seeds { class EncryptedSeed; };@@ -160,7 +160,7 @@ namespace Armory std::unique_ptrEncryption::DecryptedDataContainer decryptedData_; std::unique_ptr controlLock_; std::unique_ptrArmory::Seed::EncryptedSeed controlSeed_; std::unique_ptrArmory::Seeds::EncryptedSeed controlSeed_; unsigned encryptionVersion_ = UINT32_MAX; std::unique_ptr<PRNG_Fortuna> fortuna_;Collapse file‎cppForSwig/Wallets/WalletIdTypes.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/WalletIdTypes.cpp+64-1Lines changed: 64 additions & 1 deletionOriginal file line numberDiff line numberDiff line change@@ -1,12 +1,15 @@////////////////////////////////////////////////////////////////////////////////// //// Copyright (C) 2021-2021, goatpig //// Copyright (C) 2021-2023, goatpig //// Distributed under the MIT license //// See LICENSE-MIT or https://opensource.org/licenses/MIT //// //////////////////////////////////////////////////////////////////////////////////#include "WalletIdTypes.h"#include "DerivationScheme.h"#include "Assets.h"#include "WalletHeader.h"using namespace Armory::Wallets;@@ -655,3 +658,63 @@ EncryptionKeyId EncryptionKeyId::deserializeValue(BinaryRefReader& brr) throw IdException("EncryptionKeyId::deserializeValue"); }}///////////////////////// - wallet & master id - ///////////////////////////////std::string Armory::Wallets::generateWalletId( std::shared_ptrArmory::Assets::DerivationScheme derScheme, std::shared_ptrArmory::Assets::AssetEntry rootEntry, Armory::Seeds::SeedType sType){ auto addrVec = derScheme->extendPublicChain(rootEntry, 1, 1 + (int)sType, nullptr); if (addrVec.size() != (int)sType+1) throw WalletException("unexpected chain derivation output"); auto entry = std::dynamic_pointer_castArmory::Assets::AssetEntry_Single( addrVec[int(sType)]); if (entry == nullptr) throw WalletException("unexpected asset entry type"); return BtcUtils::computeID(entry->getPubKey()->getUncompressedKey());}////std::string Armory::Wallets::generateWalletId( SecureBinaryData pubkey, SecureBinaryData chaincode, Armory::Seeds::SeedType sType){ //sanity checks if (pubkey.empty()) throw WalletException("[generateWalletId] empty pubkey"); if (chaincode.empty()) throw WalletException("[generateWalletId] empty chaincode"); //create legacy armory derviation scheme from chaincode auto derScheme = std::make_shared< Armory::Assets::DerivationScheme_ArmoryLegacy>(chaincode); //create root pubkey asset auto asset_single = std::make_shared< Armory::Assets::AssetEntry_Single>( Armory::Wallets::AssetId::getRootAssetId(), pubkey, nullptr); //derive '(int)sType' amount of addresses, use last one as id return Armory::Wallets::generateWalletId(derScheme, asset_single, sType);}////////std::string Armory::Wallets::generateMasterId(const SecureBinaryData& pubkey, const SecureBinaryData& chaincode){ BinaryWriter bw; bw.put_BinaryData(pubkey); bw.put_BinaryData(chaincode); auto hmacMasterMsg = SecureBinaryData::fromString("MetaEntry"); auto masterID_long = BtcUtils::getHMAC256( bw.getData(), hmacMasterMsg); return BtcUtils::computeID(masterID_long);}Collapse file‎cppForSwig/Wallets/WalletIdTypes.h‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/WalletIdTypes.h+23-3Lines changed: 23 additions & 3 deletionsOriginal file line numberDiff line numberDiff line change@@ -19,7 +19,18 @@ namespace Armory namespace Bridge { class BridgePassphrasePrompt; }; } namespace Assets { class AssetEntry; class DerivationScheme; } namespace Seeds { enum class SeedType; } namespace Wallets {@@ -183,6 +194,15 @@ namespace Armory BinaryData getSerializedKey(uint8_t) const; static EncryptionKeyId deserializeValue(BinaryRefReader&); }; };}; //////////////////////////////////////////////////////////////////////// std::string generateWalletId(std::shared_ptrAssets::DerivationScheme, std::shared_ptrAssets::AssetEntry, Seeds::SeedType); std::string generateWalletId(SecureBinaryData, SecureBinaryData, Seeds::SeedType); std::string generateMasterId(const SecureBinaryData&, const SecureBinaryData&); }// namespace Wallets}#endifCollapse file‎cppForSwig/Wallets/Wallets.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/Wallets.cpp+150-242Lines changed: 150 additions & 242 deletions Load DiffLarge diffs are not rendered by default.Collapse file‎cppForSwig/Wallets/Wallets.h‎Copy file name to clipboardExpand all lines: cppForSwig/Wallets/Wallets.h+28-37Lines changed: 28 additions & 37 deletionsOriginal file line numberDiff line numberDiff line change@@ -40,9 +40,12 @@ namespace Armory class BIP32_AssetPath; } namespace Seed namespace Seeds { class EncryptedSeed; class ClearTextSeed; class ClearTextSeed_Armory135; class ClearTextSeed_BIP32; } namespace Wallets@@ -256,7 +259,7 @@ namespace Armory protected: std::shared_ptrAssets::AssetEntry_Single root_ = nullptr; std::shared_ptrSeed::EncryptedSeed seed_ = nullptr; std::shared_ptrSeeds::EncryptedSeed seed_ = nullptr; protected: //virtual@@ -284,7 +287,23 @@ namespace Armory static void importPublicData(const WalletPublicData&, std::shared_ptrIO::WalletDBInterface); void setSeed(const SecureBinaryData&, const SecureBinaryData&); void setSeed(std::unique_ptrArmory::Seeds::ClearTextSeed, const SecureBinaryData&); //wallet creation private statics static std::shared_ptr<AssetWallet_Single> createFromSeed( const std::string&, //folder Seeds::ClearTextSeed_Armory135, const SecureBinaryData&, //pass const SecureBinaryData&, //control pass unsigned); //lookup static std::shared_ptr<AssetWallet_Single> createFromSeed( const std::string&, //folder Seeds::ClearTextSeed_BIP32, const SecureBinaryData&, //pass const SecureBinaryData&, //control pass unsigned); //lookup public: //tors@@ -316,7 +335,7 @@ namespace Armory const SecureBinaryData& getDecryptedPrivateKeyForId( const AssetId&) const; std::shared_ptrSeed::EncryptedSeed getEncryptedSeed(void) const; std::shared_ptrSeeds::EncryptedSeed getEncryptedSeed(void) const; Signer::BIP32_AssetPath getBip32PathForAsset( std::shared_ptrAssets::AssetEntry) const;@@ -332,21 +351,11 @@ namespace Armory std::shared_ptrEncryption::EncryptedAssetData); //static static std::shared_ptr<AssetWallet_Single> createFromBIP32Node( const BIP32_Node& node, std::set<std::shared_ptrAccounts::AccountType_BIP32> accountTypes, const SecureBinaryData& passphrase, const SecureBinaryData& controlPassphrase, const std::string& folder); static std::shared_ptr<AssetWallet_Single> createFromPrivateRoot_Armory135( const std::string& folder, const SecureBinaryData& privateRoot, SecureBinaryData chaincode, const SecureBinaryData& passphrase, const SecureBinaryData& controlPassphrase, unsigned lookup); static std::shared_ptr<AssetWallet_Single> createFromSeed( std::unique_ptrArmory::Seeds::ClearTextSeed, const SecureBinaryData&, const SecureBinaryData&, const std::string&, unsigned lookup = 1000); static std::shared_ptr<AssetWallet_Single> createFromPublicRoot_Armory135(@@ -356,28 +365,10 @@ namespace Armory const SecureBinaryData& controlPassphrase, unsigned lookup); static std::shared_ptr<AssetWallet_Single> createFromSeed_BIP32( const std::string& folder, const SecureBinaryData& seed, const SecureBinaryData& passphrase, const SecureBinaryData& controlPassphrase, unsigned lookup); static std::shared_ptr<AssetWallet_Single> createFromSeed_BIP32_Blank( const std::string& folder, const SecureBinaryData& seed, const SecureBinaryData& passphrase, const SecureBinaryData& controlPassphrase); static std::shared_ptr<AssetWallet_Single> createBlank( const std::string& folder, const std::string& walletID, const SecureBinaryData& controlPassphrase); static std::string computeWalletID( std::shared_ptrAssets::DerivationScheme, std::shared_ptrAssets::AssetEntry); }; //////////////////////////////////////////////////////////////////////////Collapse file‎cppForSwig/gtest/SignerTests.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/gtest/SignerTests.cpp+196-256Lines changed: 196 additions & 256 deletions Load DiffLarge diffs are not rendered by default.Collapse file‎cppForSwig/gtest/SupernodeTests.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/gtest/SupernodeTests.cpp+19-18Lines changed: 19 additions & 18 deletionsOriginal file line numberDiff line numberDiff line change@@ -12,6 +12,7 @@////////////////////////////////////////////////////////////////////////////////#include "TestUtils.h"#include "../Wallets/Seeds/Seeds.h"using namespace std;using namespace Armory::Signer;using namespace Armory::Config;@@ -1762,31 +1763,31 @@ TEST_F(BlockUtilsWithWalletTest, MultipleSigners_2of3_NativeP2WSH) //// create 3 assetWlt //// //create a root private key auto&& wltRoot = CryptoPRNG::generateRandom(32); auto assetWlt_1 = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), //root as a rvalue {}, unique_ptrArmory::Seeds::ClearTextSeed seed1( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt_1 = AssetWallet_Single::createFromSeed( move(seed1), SecureBinaryData(), SecureBinaryData(), SecureBinaryData(), homedir_, 3); //set lookup computation to 3 entries wltRoot = move(CryptoPRNG::generateRandom(32)); auto assetWlt_2 = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), //root as a rvalue {}, unique_ptrArmory::Seeds::ClearTextSeed seed2( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt_2 = AssetWallet_Single::createFromSeed( move(seed2), SecureBinaryData(), SecureBinaryData(), SecureBinaryData(), homedir_, 3); //set lookup computation to 3 entries wltRoot = move(CryptoPRNG::generateRandom(32)); auto assetWlt_3 = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), //root as a rvalue {}, unique_ptrArmory::Seeds::ClearTextSeed seed3( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt_3 = AssetWallet_Single::createFromSeed( move(seed3), SecureBinaryData(), SecureBinaryData(), SecureBinaryData(), homedir_, 3); //set lookup computation to 3 entries //create 2-of-3 multisig asset entry from 3 different walletsCollapse file‎cppForSwig/gtest/WalletTests.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/gtest/WalletTests.cpp+785-383Lines changed: 785 additions & 383 deletions Load DiffLarge diffs are not rendered by default.Collapse file‎cppForSwig/gtest/ZeroConfTests.cpp‎Copy file name to clipboardExpand all lines: cppForSwig/gtest/ZeroConfTests.cpp+38-37Lines changed: 38 additions & 37 deletionsOriginal file line numberDiff line numberDiff line change@@ -12,6 +12,7 @@////////////////////////////////////////////////////////////////////////////////#include "TestUtils.h"#include "../Wallets/Seeds/Seeds.h"using namespace std;using namespace Armory::Signer;using namespace Armory::Config;@@ -2364,15 +2365,15 @@ TEST_F(ZeroConfTests_FullNode, Replace_ZC_Test) //// create assetWlt //// //create a root private key auto&& wltRoot = CryptoPRNG::generateRandom(32); auto assetWlt = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), //root as a r value {}, unique_ptrArmory::Seeds::ClearTextSeed seed( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt = AssetWallet_Single::createFromSeed( move(seed), SecureBinaryData(), SecureBinaryData(), homedir_, 10); //set lookup computation to 5 entries //register with db vector addrVec;@@ -2877,13 +2878,13 @@ TEST_F(ZeroConfTests_FullNode, RegisterAddress_AfterZC) //// create assetWlt //// //create a root private key auto&& wltRoot = CryptoPRNG::generateRandom(32); auto assetWlt = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), //root as a r value {}, unique_ptrArmory::Seeds::ClearTextSeed seed( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt = AssetWallet_Single::createFromSeed( move(seed), SecureBinaryData(), SecureBinaryData(), homedir_, 3); //set lookup computation to 3 entries //register with db@@ -3095,14 +3096,14 @@ TEST_F(ZeroConfTests_FullNode, ChainZC_RBFchild_Test) //// create assetWlt //// //create a root private key auto&& wltRoot = CryptoPRNG::generateRandom(32); auto assetWlt = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), //root as a r value {}, unique_ptrArmory::Seeds::ClearTextSeed seed( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt = AssetWallet_Single::createFromSeed( move(seed), SecureBinaryData(), SecureBinaryData(), 10); //set lookup computation to 10 entries SecureBinaryData(), homedir_, 10); //set lookup computation to 3 entries //register with db vector addrVec;@@ -3576,14 +3577,14 @@ TEST_F(ZeroConfTests_FullNode, TwoZC_CheckLedgers) //// create assetWlt //// //create a root private key auto&& wltRoot = CryptoPRNG::generateRandom(32); auto assetWlt = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), {}, SecureBinaryData(), //empty passphrase unique_ptrArmory::Seeds::ClearTextSeed seed( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt = AssetWallet_Single::createFromSeed( move(seed), SecureBinaryData(), SecureBinaryData(), 5); homedir_, 5); //set lookup computation to 3 entries //register with db vector addrVec;@@ -4375,13 +4376,13 @@ TEST_F(ZeroConfTests_Supernode, ZC_Reorg) theBDMt_->start(DBSettings::initMode()); auto&& bdvID = DBTestUtils::registerBDV(clients_, BitcoinSettings::getMagicBytes()); auto&& wltRoot = CryptoPRNG::generateRandom(32); auto assetWlt = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), //root as a rvalue {}, unique_ptrArmory::Seeds::ClearTextSeed seed( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt = AssetWallet_Single::createFromSeed( move(seed), SecureBinaryData(), SecureBinaryData(), homedir_, 3); //set lookup computation to 3 entries auto addr1_ptr = assetWlt->getNewAddress(); auto addr2_ptr = assetWlt->getNewAddress();@@ -4546,14 +4547,14 @@ TEST_F(ZeroConfTests_Supernode, ChainZC_RBFchild_Test) //// create assetWlt //// //create a root private key auto&& wltRoot = CryptoPRNG::generateRandom(32); auto assetWlt = AssetWallet_Single::createFromPrivateRoot_Armory135( homedir_, move(wltRoot), //root as a r value {}, unique_ptrArmory::Seeds::ClearTextSeed seed( new Armory::Seeds::ClearTextSeed_Armory135()); auto assetWlt = AssetWallet_Single::createFromSeed( move(seed), SecureBinaryData(), SecureBinaryData(), 10); //set lookup computation to 5 entries SecureBinaryData(), homedir_, 10); //set lookup computation to 3 entries //register with db vector addrVec;Collapse file‎cppForSwig/protobuf/BridgeProto.proto‎Copy file name to clipboardExpand all lines: cppForSwig/protobuf/BridgeProto.proto+34-19Lines changed: 34 additions & 19 deletionsOriginal file line numberDiff line numberDiff line change@@ -11,32 +11,47 @@ message RestoreWalletPayload optional string spPass = 3;}enum RestorePromptType{ FormatError = 1; Failure = 2; ChecksumError = 3; DecryptError = 4; Passphrase = 5; Control = 6; Id = 7; TypeError = 8; Success = 9; UnknownError = 10;}message RestorePrompt{ message TypeError { required string error = 1; } message ChecksumIndexes { repeated int32 index = 1; } message CheckWalletId { required string wallet_id = 1; required int32 backup_type = 2; } oneof prompt { CheckWalletId check_wallet_id = 10; bool get_passphrases = 11; bool decrypt_error = 12; required RestorePromptType promptType = 1; repeated int32 checksums = 2; optional string extra = 3; TypeError type_error = 20; ChecksumIndexes checksum_error = 21; ChecksumIndexes checksum_mismatch = 22; }}message RestoreReply{ required bool result = 1; optional bytes extra = 2; message Passphrases { required string control = 1; required string privkey = 2; } required bool success = 1; oneof reply { Passphrases passphrases = 11; }}////////////////////////////////////////////////////////////////////////////////Collapse file‎qtdialogs/DlgRestore.py‎Copy file name to clipboardExpand all lines: qtdialogs/DlgRestore.py+17-20Lines changed: 17 additions & 20 deletionsOriginal file line numberDiff line numberDiff line change@@ -160,7 +160,7 @@ def init(self, parent, main, thisIsATest=False, expectWltID=None): self.setWindowTitle(self.tr('Test Single-Sheet Backup')) else: self.setWindowTitle(self.tr('Restore Single-Sheet Backup')) self.connect(self.chkEncrypt, SIGNAL("clicked()"), self.onEncryptCheckboxChange) self.chkEncrypt.clicked.connect(self.onEncryptCheckboxChange) self.setMinimumWidth(500) self.layout().setSizeConstraint(QLayout.SetFixedSize)@@ -469,8 +469,8 @@ def init(self, parent, main, thisIsATest=False, expectWltID=None): self.btnAddFrag = QPushButton(self.tr('+Frag')) self.btnRmFrag = QPushButton(self.tr('-Frag')) self.btnRmFrag.setVisible(False) self.connect(self.btnAddFrag, SIGNAL(CLICKED), self.addFragment) self.connect(self.btnRmFrag, SIGNAL(CLICKED), self.removeFragment) self.btnAddFrag.clicked.connect(self.addFragment) self.btnRmFrag.clicked.connect(self.removeFragment) self.chkEncrypt = QCheckBox(self.tr('Encrypt Restored Wallet')) self.chkEncrypt.setChecked(True) frmAddRm = makeHorizFrame([self.chkEncrypt, STRETCH, self.btnRmFrag, self.btnAddFrag])@@ -484,8 +484,8 @@ def init(self, parent, main, thisIsATest=False, expectWltID=None): btnExit = QPushButton(self.tr('Cancel')) self.btnRestore = QPushButton(doItText) self.connect(btnExit, SIGNAL(CLICKED), self.reject) self.connect(self.btnRestore, SIGNAL(CLICKED), self.processFrags) btnExit.clicked.connect(self.reject) self.btnRestore.clicked.connect(self.processFrags) frmBtns = makeHorizFrame([btnExit, STRETCH, self.btnRestore]) self.lblRightFrm = QRichLabel('', hAlign=Qt.AlignHCenter)@@ -538,7 +538,7 @@ def init(self, parent, main, thisIsATest=False, expectWltID=None): self.chkEncrypt.setVisible(not thisIsATest) self.advancedOptionsTab.setEnabled(not thisIsATest) if not thisIsATest: self.connect(self.chkEncrypt, SIGNAL(CLICKED), self.onEncryptCheckboxChange) self.chkEncrypt.clicked.connect(self.onEncryptCheckboxChange) layout = QVBoxLayout() layout.addWidget(walletRestoreTabs)@@ -578,12 +578,9 @@ def makeFragInputTable(self, addCount=0): lblFragID.setText('' + fid + '', color='TextWarn') self.connect(btnEnter, SIGNAL(CLICKED), \ functools.partial(self.dataEnter, fnum=i)) self.connect(btnLoad, SIGNAL(CLICKED), \ functools.partial(self.dataLoad, fnum=i)) self.connect(btnClear, SIGNAL(CLICKED), \ functools.partial(self.dataClear, fnum=i)) btnEnter.clicked.connect(functools.partial(self.dataEnter, fnum=i)) btnLoad.clicked.connect(functools.partial(self.dataLoad, fnum=i)) btnClear.clicked.connect(functools.partial(self.dataClear, fnum=i)) newLayout.addWidget(btnEnter, 2 * i + 1, 0)@@ -1025,7 +1022,7 @@ def init(self, parent, main, fragList=[], wltType=UNKNOWN, securePrintCode=N self.backupTypeButtonGroup.addButton(self.version135cButton) self.backupTypeButtonGroup.addButton(self.version135cSPButton) self.version135cButton.setChecked(True) self.connect(self.backupTypeButtonGroup, SIGNAL('buttonClicked(int)'), self.changeType) self.backupTypeButtonGroup.buttonClicked.connect(self.changeType) # This value will be locked after the first fragment is entered. if wltType == UNKNOWN:@@ -1104,8 +1101,8 @@ def init(self, parent, main, fragList=[], wltType=UNKNOWN, securePrintCode=N self.btnAccept = QPushButton(self.tr("Done")) self.btnCancel = QPushButton(self.tr("Cancel")) self.connect(self.btnAccept, SIGNAL(CLICKED), self.verifyUserInput) self.connect(self.btnCancel, SIGNAL(CLICKED), self.reject) self.btnAccept.clicked.connect(self.verifyUserInput) self.btnCancel.clicked.connect(self.reject) buttonBox = QDialogButtonBox() buttonBox.addButton(self.btnAccept, QDialogButtonBox.AcceptRole) buttonBox.addButton(self.btnCancel, QDialogButtonBox.RejectRole)@@ -1291,9 +1288,9 @@ def init(self, parent, main, thisIsATest=False, expectWltID=None): self.btnLoad = QPushButton(self.tr("Load From Text File")) self.btnAccept = QPushButton(doItText) self.btnCancel = QPushButton(self.tr("Cancel")) self.connect(self.btnLoad, SIGNAL("clicked()"), self.loadWODataFile) self.connect(self.btnAccept, SIGNAL("clicked()"), self.verifyUserInput) self.connect(self.btnCancel, SIGNAL("clicked()"), self.reject) self.btnLoad.clicked.connect(self.loadWODataFile) self.btnAccept.clicked.connect(self.verifyUserInput) self.btnCancel.clicked.connect(self.reject) buttonBox = QDialogButtonBox() buttonBox.addButton(self.btnLoad, QDialogButtonBox.AcceptRole) buttonBox.addButton(self.btnAccept, QDialogButtonBox.AcceptRole)@@ -1490,8 +1487,8 @@ def init(self, parent, main): self.btnAccept = QPushButton(self.tr("Done")) self.btnCancel = QPushButton(self.tr("Cancel")) self.connect(self.btnAccept, SIGNAL(CLICKED), self.verifySecurePrintCode) self.connect(self.btnCancel, SIGNAL(CLICKED), self.reject) self.btnAccept.clicked.connect(self.verifySecurePrintCode) self.btnCancel.clicked.connect(self.reject) buttonBox = QDialogButtonBox() buttonBox.addButton(self.btnAccept, QDialogButtonBox.AcceptRole) buttonBox.addButton(self.btnCancel, QDialogButtonBox.RejectRole)Collapse file‎qtdialogs/DlgUniversalRestoreSelect.py‎Copy file name to clipboardExpand all lines: qtdialogs/DlgUniversalRestoreSelect.py+1-1Lines changed: 1 addition & 1 deletionOriginal file line numberDiff line numberDiff line change@@ -21,7 +21,7 @@################################################################################class DlgUniversalRestoreSelect(ArmoryDialog): ############################################################################# ############################################################################# def init(self, parent, main): super(DlgUniversalRestoreSelect, self).init(parent, main)
0 commit commentsComments0 (0)CommentSubscribeYou're not receiving notifications from this thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants