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
#pragma once
8

9
#include <TrustWalletCore/TWCoinType.h>
10
#include <TrustWalletCore/TWPurpose.h>
11

12
#include <cstdint>
13
#include <initializer_list>
14
#include <string>
15
#include <vector>
16

17
namespace TW {
18

19
struct DerivationPathIndex {
20 1
    uint32_t value = 0;
21 1
    bool hardened = true;
22

23 1
    DerivationPathIndex() = default;
24 1
    DerivationPathIndex(uint32_t value, bool hardened = true) : value(value), hardened(hardened) {}
25

26
    /// The derivation index.
27 1
    uint32_t derivationIndex() const {
28 1
        if (hardened) {
29 1
            return value | 0x80000000;
30
        } else {
31 1
            return value;
32
        }
33
    }
34

35 1
    std::string string() const {
36 1
        if (hardened) {
37 1
            return std::to_string(value) + "'";
38
        } else {
39 1
            return std::to_string(value);
40
        }
41
    }
42
};
43

44
/// A BIP32 HD wallet derivation path.
45 1
struct DerivationPath {
46
    std::vector<DerivationPathIndex> indices;
47

48 1
    TWPurpose purpose() const {
49 1
        if (indices.size() == 0) { return TWPurposeBIP44; }
50 1
        return static_cast<TWPurpose>(indices[0].value);
51
    }
52

53 1
    void setPurpose(TWPurpose v) {
54 1
        if (indices.size() == 0) { return; }
55 1
        indices[0] = DerivationPathIndex(v, /* hardened: */ true);
56
    }
57

58 1
    uint32_t coin() const {
59 1
        if (indices.size() <= 1) { return TWCoinTypeBitcoin; }
60 1
        return indices[1].value;
61
    }
62

63 1
    void setCoin(uint32_t v) {
64 1
        if (indices.size() <= 1) { return; }
65 1
        indices[1] = DerivationPathIndex(v, /* hardened: */ true);
66
    }
67

68 1
    uint32_t account() const {
69 1
        if (indices.size() <= 2) { return 0; }
70 1
        return indices[2].value;
71
    }
72

73 1
    void setAccount(uint32_t v) {
74 1
        if (indices.size() <= 2) { return; }
75 1
        indices[2] = DerivationPathIndex(v, /* hardened: */ true);
76
    }
77

78 1
    uint32_t change() const {
79 1
        if (indices.size() <= 3) { return 0; }
80 1
        return indices[3].value;
81
    }
82

83 1
    void setChange(uint32_t v) {
84 1
        if (indices.size() <= 3) { return; }
85 1
        indices[3] = DerivationPathIndex(v, /* hardened: */ false);
86
    }
87

88 1
    uint32_t address() const {
89 1
        if (indices.size() <= 4) { return 0; }
90 1
        return indices[4].value;
91
    }
92

93 1
    void setAddress(uint32_t v) {
94 1
        if (indices.size() <= 4) { return; }
95 1
        indices[4] = DerivationPathIndex(v, /* hardened: */ false);
96
    }
97

98 1
    DerivationPath() = default;
99 1
    explicit DerivationPath(std::initializer_list<DerivationPathIndex> l) : indices(l) {}
100
    explicit DerivationPath(std::vector<DerivationPathIndex> indices) : indices(std::move(indices)) {}
101

102
    /// Creates a `DerivationPath` by BIP44 components.
103 1
    DerivationPath(TWPurpose purpose, uint32_t coin, uint32_t account, uint32_t change,
104
                   uint32_t address) 
105 1
    : indices(std::vector<DerivationPathIndex>(5)) {
106 1
        setPurpose(purpose);
107 1
        setCoin(coin);
108 1
        setAccount(account);
109 1
        setChange(change);
110 1
        setAddress(address);
111
    }
112

113
    /// Creates a derivation path with a string description like `m/10/0/2'/3`
114
    ///
115
    /// @throws std::invalid_argument if the string is not a valid derivation
116
    /// path.
117
    explicit DerivationPath(const std::string& string);
118

119
    /// String representation.
120
    std::string string() const noexcept;
121
};
122

123 1
inline bool operator==(const DerivationPathIndex& lhs, const DerivationPathIndex& rhs) {
124 1
    return lhs.value == rhs.value && lhs.hardened == rhs.hardened;
125
}
126

127 1
inline bool operator==(const DerivationPath& lhs, const DerivationPath& rhs) {
128 1
    return std::equal(lhs.indices.begin(), lhs.indices.end(), rhs.indices.begin(),
129 1
                      rhs.indices.end());
130
}
131

132
} // namespace TW

Read our documentation on viewing source code .

Loading