1
// Copyright © 2017-2020 Trust Wallet.
2
//
3
// This file is part of Trust. The full Trust copyright notice, including
4
// terms governing use, modification, and redistribution, is contained in the
5
// file LICENSE at the root of the source code distribution tree.
6

7
#include "Keys.h"
8

9
#include "WalletConsole.h"
10
#include "Data.h"
11
#include "PrivateKey.h"
12
#include "HexCoding.h"
13
#include "HDWallet.h"
14
#include "Coin.h"
15

16
#include <iostream>
17
#include <vector>
18
#include <cassert>
19

20
namespace TW::WalletConsole {
21

22
using namespace std;
23

24 1
Keys::Keys(ostream& out, const Coins& coins) : _out(out), _coins(coins) {
25
    // init a random mnemonic
26 1
    HDWallet newwall(128, "");
27 1
    _currentMnemonic = newwall.mnemonic;
28
}
29

30 1
void privateKeyToResult(const PrivateKey& priKey, string& res_out) {
31
    // take the key, but may need to take extension as well
32 1
    res_out = hex(priKey.bytes);
33 1
    if (priKey.extensionBytes.size() > 0) {
34 0
        res_out += hex(priKey.extensionBytes);
35 0
        res_out += hex(priKey.chainCodeBytes);
36
    }
37
}
38

39 1
bool Keys::newKey(const string& coinid, string& res) {
40
    // Create a new private key by creating a new HDWallet and deriving from it
41
    // Use coin-specific derivation path, so that PK can be coin-specific (e.g. longer for Cardano)
42
    // coin
43 1
    Coin coin;
44 1
    if (!_coins.findCoin(coinid, coin)) { return false; }
45

46 1
    HDWallet newWallet(256, "");
47

48 1
    DerivationPath derivationPath = DerivationPath(coin.derivPath);
49 1
    PrivateKey key = newWallet.getKey(TWCoinType(coin.c), derivationPath);
50 1
    privateKeyToResult(key, res);
51 1
    return true;
52
}
53

54 1
bool Keys::pubPri(const string& coinid, const string& p, string& res) {
55 1
    Coin coin;
56 1
    if (!_coins.findCoin(coinid, coin)) { return false; }
57 1
    Data privDat;
58
    try {
59 1
        privDat = parse_hex(p);
60 1
        auto priv = PrivateKey(privDat);
61 1
        auto pub = priv.getPublicKey((TWPublicKeyType)coin.pubKeyType);
62 1
        res = hex(pub.bytes);
63 1
        _out << "Public key created, type " << (int)coin.pubKeyType << ", length " << pub.bytes.size() << endl;
64 1
        return true;
65 1
    } catch (exception& ex) {
66 1
        _out << "Error: " << ex.what() << endl;
67 1
        return false; 
68
    }
69
}
70

71 1
bool Keys::priPub(const string& p, string& res) {
72 1
    _out << "Not yet implemented! :)" << endl;
73 1
    return false;
74
}
75

76 1
void Keys::setMnemonic(const vector<string>& param) {
77 1
    if (param.size() < 1 + 12) {
78 1
        _out << "Error: at least 12 words are needed for the mnemonic!" << endl;
79 1
        return;
80
    }
81
    // concatenate
82 1
    string mnem = "";
83 1
    for (int i = 1; i < param.size(); ++i) {
84 1
        if (i > 1) mnem += " ";
85 1
        mnem += param[i]; 
86
    }
87

88
    // verify mnemonic
89 1
    if (!HDWallet::isValid(mnem)) {
90 1
        _out << "Not a valid mnemonic: " << mnem << endl;
91 1
        return;
92
    }
93

94
    // store
95 1
    _currentMnemonic = mnem;
96 1
    _out << "Mnemonic set (" << param.size() - 1 << " words)." << endl;
97
}
98

99 1
bool Keys::newMnemonic(const string& param1, string& res) {
100 1
    int strength = stoi(param1);
101 1
    if (strength < 128 || strength > 256 || (strength % 32 != 0)) {
102 0
        _out << "Error: strength must be between 128 and 256, and multiple of 32" << endl;
103 0
        return false;
104
    }
105 1
    HDWallet newwall(strength, "");
106 1
    if (newwall.mnemonic.length() == 0) {
107 0
        _out << "Error: no mnemonic generated." << endl;
108 0
        return false;
109
    }
110
    // store
111 1
    _currentMnemonic = newwall.mnemonic;
112 1
    res = _currentMnemonic;
113 1
    _out << "New mnemonic set." << endl;
114 1
    return false;
115
}
116

117 1
bool Keys::dumpSeed(string& res) {
118 1
    assert(_currentMnemonic.length() > 0); // a mnemonic is always set
119 1
    HDWallet wallet(_currentMnemonic, "");
120 1
    string seedHex = hex(wallet.seed);
121 1
    res = seedHex;
122
    return true;
123
}
124

125 1
bool Keys::dumpMnemonic(string& res) {
126 1
    assert(_currentMnemonic.length() > 0); // a mnemonic is always set
127 1
    res = _currentMnemonic;
128 1
    return true;
129
}
130

131 1
bool Keys::dumpDP(const string& coinid, string& res) {
132 1
    Coin coin;
133 1
    if (!_coins.findCoin(coinid, coin)) { return false; }
134 1
    res = coin.derivPath;
135 1
    return true;
136
}
137

138 1
bool Keys::dumpXpub(const string& coinid, string& res) {
139 1
    assert(_currentMnemonic.length() > 0); // a mnemonic is always set
140 1
    Coin coin;
141 1
    if (!_coins.findCoin(coinid, coin)) { return false; }
142 1
    TWCoinType ctype = (TWCoinType)coin.c;
143 1
    TWPurpose purpose = TW::purpose(ctype);
144 1
    TWHDVersion xpubVersion = TW::xpubVersion(ctype);
145 1
    HDWallet wallet(_currentMnemonic, "");
146 1
    string xpub = wallet.getExtendedPublicKey(purpose, ctype, xpubVersion);
147 1
    res = xpub;
148 1
    return true;
149
}
150

151 1
bool Keys::priDP(const string& coinid, const string& dp, string& res) {
152
    // coin
153 1
    Coin coin;
154 1
    if (!_coins.findCoin(coinid, coin)) { return false; }
155

156
    // mnemo
157 1
    assert(_currentMnemonic.length() > 0); // a mnemonic is always set
158

159
    // derivation path
160 1
    string dp2 = dp;
161 1
    if (dp2.length() == 0) {
162
        // missing dp, use default
163 0
        dp2 = coin.derivPath;
164
    }
165 1
    DerivationPath dp3(dp2);
166 1
    _out << "Using derivation path \"" << dp2 << "\" for coin " << coin.name << endl;
167

168 1
    HDWallet wallet(_currentMnemonic, "");
169 1
    PrivateKey priKey = wallet.getKey(TWCoinType(coin.c), dp3);
170

171 1
    privateKeyToResult(priKey, res);
172 1
    return true;
173
}
174

175
} // namespace TW::WalletConsole

Read our documentation on viewing source code .

Loading