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 "Serialization.h"
8

9
#include "Address.h"
10
#include "Bech32Address.h"
11
#include "Ethereum/Address.h"
12
#include "../HexCoding.h"
13

14
using namespace TW;
15
using namespace TW::Binance;
16
using namespace google::protobuf;
17

18
using json = nlohmann::json;
19

20 1
static inline std::string addressString(const std::string& bytes) {
21 1
    auto data = Data(bytes.begin(), bytes.end());
22 1
    return Address(data).string();
23
}
24

25 1
static inline std::string validatorAddress(const std::string& bytes) {
26 1
    auto data = Data(bytes.begin(), bytes.end());
27 1
    return Bech32Address(Address::hrpValidator, data).string();
28
}
29

30 1
json Binance::signatureJSON(const Proto::SigningInput& input) {
31 1
    json j;
32 1
    j["account_number"] = std::to_string(input.account_number());
33 1
    j["chain_id"] = input.chain_id();
34 1
    j["data"] = nullptr;
35 1
    j["memo"] = input.memo();
36 1
    j["msgs"] = json::array({orderJSON(input)});
37 1
    j["sequence"] = std::to_string(input.sequence());
38 1
    j["source"] = std::to_string(input.source());
39 1
    return j;
40
}
41

42 1
json Binance::orderJSON(const Proto::SigningInput& input) {
43 1
    json j;
44 1
    if (input.has_trade_order()) {
45 1
        j["id"] = input.trade_order().id();
46 1
        j["ordertype"] = 2;
47 1
        j["price"] = input.trade_order().price();
48 1
        j["quantity"] = input.trade_order().quantity();
49 1
        j["sender"] = addressString(input.trade_order().sender());
50 1
        j["side"] = input.trade_order().side();
51 1
        j["symbol"] = input.trade_order().symbol();
52 1
        j["timeinforce"] = input.trade_order().timeinforce();
53 1
    } else if (input.has_cancel_trade_order()) {
54 0
        j["refid"] = input.cancel_trade_order().refid();
55 0
        j["sender"] = addressString(input.cancel_trade_order().sender());
56 0
        j["symbol"] = input.cancel_trade_order().symbol();
57 1
    } else if (input.has_send_order()) {
58 1
        j["inputs"] = inputsJSON(input.send_order());
59 1
        j["outputs"] = outputsJSON(input.send_order());
60 1
    } else if (input.has_freeze_order()) {
61 1
        j["from"] = addressString(input.freeze_order().from());
62 1
        j["symbol"] = input.freeze_order().symbol();
63 1
        j["amount"] = input.freeze_order().amount();
64 1
    } else if (input.has_unfreeze_order()) {
65 1
        j["from"] = addressString(input.unfreeze_order().from());
66 1
        j["symbol"] = input.unfreeze_order().symbol();
67 1
        j["amount"] = input.unfreeze_order().amount();
68 1
    } else if (input.has_htlt_order()) {
69 1
        j["from"] = addressString(input.htlt_order().from());
70 1
        j["to"] = addressString(input.htlt_order().to());
71 1
        j["recipient_other_chain"] = input.htlt_order().recipient_other_chain();
72 1
        j["sender_other_chain"] = input.htlt_order().sender_other_chain();
73 1
        j["random_number_hash"] = hex(input.htlt_order().random_number_hash());
74 1
        j["timestamp"] = input.htlt_order().timestamp();
75 1
        j["amount"] = tokensJSON(input.htlt_order().amount());
76 1
        j["expected_income"] = input.htlt_order().expected_income();
77 1
        j["height_span"] = input.htlt_order().height_span();
78 1
        j["cross_chain"] = input.htlt_order().cross_chain();
79 1
    } else if (input.has_deposithtlt_order()) {
80 1
        j["from"] = addressString(input.deposithtlt_order().from());
81 1
        j["swap_id"] = hex(input.deposithtlt_order().swap_id());
82 1
        j["amount"] = tokensJSON(input.deposithtlt_order().amount());
83 1
    } else if (input.has_claimhtlt_order()) {
84 1
        j["from"] = addressString(input.claimhtlt_order().from());
85 1
        j["swap_id"] = hex(input.claimhtlt_order().swap_id());
86 1
        j["random_number"] = hex(input.claimhtlt_order().random_number());
87 1
    } else if (input.has_refundhtlt_order()) {
88 1
        j["from"] = addressString(input.refundhtlt_order().from());
89 1
        j["swap_id"] = hex(input.refundhtlt_order().swap_id());
90 1
    } else if (input.has_transfer_out_order()) {
91 1
        auto to = input.transfer_out_order().to();
92 1
        auto addr = Ethereum::Address(Data(to.begin(), to.end()));
93 1
        j["from"] = addressString(input.transfer_out_order().from());
94 1
        j["to"] = addr.string();
95 1
        j["amount"] = tokenJSON(input.transfer_out_order().amount());
96 1
        j["expire_time"] = input.transfer_out_order().expire_time();
97 1
    } else if (input.has_side_delegate_order()) {
98 1
        j["type"] = "cosmos-sdk/MsgSideChainDelegate";
99 1
        j["value"] = {
100 1
            {"delegator_addr", addressString(input.side_delegate_order().delegator_addr())},
101 1
            {"validator_addr",validatorAddress(input.side_delegate_order().validator_addr())},
102 1
            {"delegation", tokenJSON(input.side_delegate_order().delegation(), true)},
103 1
            {"side_chain_id", input.side_delegate_order().chain_id()},
104
        };
105 1
    } else if (input.has_side_redelegate_order()) {
106 1
        j["type"] = "cosmos-sdk/MsgSideChainRedelegate";
107 1
        j["value"] = {
108 1
            {"delegator_addr", addressString(input.side_redelegate_order().delegator_addr())},
109 1
            {"validator_src_addr", validatorAddress(input.side_redelegate_order().validator_src_addr())},
110 1
            {"validator_dst_addr", validatorAddress(input.side_redelegate_order().validator_dst_addr())},
111 1
            {"amount", tokenJSON(input.side_redelegate_order().amount(), true)},
112 1
            {"side_chain_id", input.side_redelegate_order().chain_id()},
113
        };
114 1
    } else if (input.has_side_undelegate_order()) {
115 1
        j["type"] = "cosmos-sdk/MsgSideChainUndelegate";
116 1
        j["value"] = {
117 1
            {"delegator_addr", addressString(input.side_undelegate_order().delegator_addr())},
118 1
            {"validator_addr", validatorAddress(input.side_undelegate_order().validator_addr())},
119 1
            {"amount", tokenJSON(input.side_undelegate_order().amount(), true)},
120 1
            {"side_chain_id", input.side_undelegate_order().chain_id()},
121
        };
122 1
    } else if (input.has_time_lock_order()) {
123 1
        j["from"] = addressString(input.time_lock_order().from_address());
124 1
        j["description"] = input.time_lock_order().description();
125 1
        j["amount"] = tokensJSON(input.time_lock_order().amount());
126 1
        j["lock_time"] = input.time_lock_order().lock_time();
127 1
    } else if (input.has_time_relock_order()) {
128 1
        const auto amount = input.time_relock_order().amount();
129 1
        j["from"] = addressString(input.time_relock_order().from_address());
130 1
        j["time_lock_id"] = input.time_relock_order().id();
131 1
        j["description"] = input.time_relock_order().description();
132
        // if amount is empty or omitted, set null to avoid signature verification error
133 1
        j["amount"] = nullptr;
134 1
        if (amount.size() > 0) {
135 1
            j["amount"] = tokensJSON(amount);
136
        }
137 1
        j["lock_time"] = input.time_relock_order().lock_time();
138 1
    } else if (input.has_time_unlock_order()) {
139 1
        j["from"] = addressString(input.time_unlock_order().from_address());
140 1
        j["time_lock_id"] = input.time_unlock_order().id();
141
    }
142 1
    return j;
143
}
144

145 1
json Binance::inputsJSON(const Proto::SendOrder& order) {
146 1
    json j = json::array();
147 1
    for (auto& input : order.inputs()) {
148 1
        j.push_back({
149 1
            {"address", addressString(input.address())},
150 1
            {"coins", tokensJSON(input.coins())}
151
        });
152
    }
153 1
    return j;
154
}
155

156 1
json Binance::outputsJSON(const Proto::SendOrder& order) {
157 1
    json j = json::array();
158 1
    for (auto& output : order.outputs()) {
159 1
        j.push_back({
160 1
            {"address", addressString(output.address())},
161 1
            {"coins", tokensJSON(output.coins())}
162
        });
163
    }
164 1
    return j;
165
}
166

167 1
json Binance::tokenJSON(const Proto::SendOrder_Token& token, bool stringAmount) {
168 1
    json j = { {"denom", token.denom()} };
169 1
    if (stringAmount) {
170 1
        j["amount"] = std::to_string(token.amount());
171 1
    } else {
172 1
        j["amount"] = token.amount();
173
    }
174 1
    return j;
175
}
176

177 1
json Binance::tokensJSON(const RepeatedPtrField<Proto::SendOrder_Token>& tokens) {
178 1
    json j = json::array();
179 1
    for (auto& token : tokens) {
180 1
        j.push_back(tokenJSON(token));
181
    }
182 1
    return j;
183
}

Read our documentation on viewing source code .

Loading