walletutil.cpp raw

   1  // Copyright (c) 2017-2022 The Limenka developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #include <wallet/walletutil.h>
   6  
   7  #include <chainparams.h>
   8  #include <common/args.h>
   9  #include <key_io.h>
  10  #include <logging.h>
  11  
  12  namespace wallet {
  13  fs::path GetWalletDir()
  14  {
  15      fs::path path;
  16  
  17      if (gArgs.IsArgSet("-walletdir")) {
  18          path = gArgs.GetPathArg("-walletdir");
  19          if (!fs::is_directory(path)) {
  20              // If the path specified doesn't exist, we return the deliberately
  21              // invalid empty string.
  22              path = "";
  23          }
  24      } else {
  25          path = gArgs.GetDataDirNet();
  26          // If a wallets directory exists, use that, otherwise default to GetDataDir
  27          if (fs::is_directory(path / "wallets")) {
  28              path /= "wallets";
  29          }
  30      }
  31  
  32      return path;
  33  }
  34  
  35  bool IsFeatureSupported(int wallet_version, int feature_version)
  36  {
  37      return wallet_version >= feature_version;
  38  }
  39  
  40  WalletFeature GetClosestWalletFeature(int version)
  41  {
  42      static constexpr std::array wallet_features{FEATURE_LATEST, FEATURE_PRE_SPLIT_KEYPOOL, FEATURE_NO_DEFAULT_KEY, FEATURE_HD_SPLIT, FEATURE_HD, FEATURE_COMPRPUBKEY, FEATURE_WALLETCRYPT, FEATURE_BASE};
  43      for (const WalletFeature& wf : wallet_features) {
  44          if (version >= wf) return wf;
  45      }
  46      return static_cast<WalletFeature>(0);
  47  }
  48  
  49  WalletDescriptor GenerateWalletDescriptor(const CExtPubKey& master_key, const OutputType& addr_type, bool internal)
  50  {
  51      int64_t creation_time = GetTime();
  52  
  53      std::string xpub = EncodeExtPubKey(master_key);
  54  
  55      // Build descriptor string
  56      std::string desc_prefix;
  57      std::string desc_suffix = "/*)";
  58      switch (addr_type) {
  59      case OutputType::LEGACY: {
  60          desc_prefix = "pkh(" + xpub + "/44h";
  61          break;
  62      }
  63      case OutputType::P2SH_SEGWIT: {
  64          desc_prefix = "sh(wpkh(" + xpub + "/49h";
  65          desc_suffix += ")";
  66          break;
  67      }
  68      case OutputType::BECH32: {
  69          desc_prefix = "wpkh(" + xpub + "/84h";
  70          break;
  71      }
  72      case OutputType::BECH32M: {
  73          desc_prefix = "tr(" + xpub + "/86h";
  74          break;
  75      }
  76      case OutputType::P2SPKH: {
  77          desc_prefix = "spk(" + xpub + "/87h";
  78          break;
  79      }
  80      case OutputType::UNKNOWN: {
  81          // We should never have a DescriptorScriptPubKeyMan for an UNKNOWN OutputType,
  82          // so if we get to this point something is wrong
  83          assert(false);
  84      }
  85      } // no default case, so the compiler can warn about missing cases
  86      assert(!desc_prefix.empty());
  87  
  88      // Mainnet derives at 0', testnet and regtest derive at 1'
  89      if (Params().IsTestChain()) {
  90          desc_prefix += "/1h";
  91      } else {
  92          desc_prefix += "/0h";
  93      }
  94  
  95      std::string internal_path = internal ? "/1" : "/0";
  96      std::string desc_str = desc_prefix + "/0h" + internal_path + desc_suffix;
  97  
  98      // Make the descriptor
  99      FlatSigningProvider keys;
 100      std::string error;
 101      std::vector<std::unique_ptr<Descriptor>> desc = Parse(desc_str, keys, error, false);
 102      WalletDescriptor w_desc(std::move(desc.at(0)), creation_time, 0, 0, 0);
 103      return w_desc;
 104  }
 105  
 106  } // namespace wallet
 107