Skip to content

Commit

Permalink
Merge pull request #5267 from brave/fix-9250
Browse files Browse the repository at this point in the history
Showing all deposit addresses in the Binance Widget.
  • Loading branch information
ryanml committed May 3, 2020
1 parent d9797ab commit c56b020
Show file tree
Hide file tree
Showing 17 changed files with 433 additions and 84 deletions.
36 changes: 34 additions & 2 deletions browser/extensions/api/binance_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ BinanceGetDepositInfoFunction::Run() {

auto* service = GetBinanceService(browser_context());
bool info_request = service->GetDepositInfo(params->symbol,
params->ticker_network,
base::BindOnce(
&BinanceGetDepositInfoFunction::OnGetDepositInfo, this));

Expand All @@ -267,11 +268,11 @@ BinanceGetDepositInfoFunction::Run() {

void BinanceGetDepositInfoFunction::OnGetDepositInfo(
const std::string& deposit_address,
const std::string& deposit_url,
const std::string& deposit_tag,
bool success) {
Respond(TwoArguments(
std::make_unique<base::Value>(deposit_address),
std::make_unique<base::Value>(deposit_url)));
std::make_unique<base::Value>(deposit_tag)));
}

ExtensionFunction::ResponseAction
Expand Down Expand Up @@ -362,5 +363,36 @@ void BinanceRevokeTokenFunction::OnRevokeToken(bool success) {
Respond(OneArgument(std::make_unique<base::Value>(success)));
}

ExtensionFunction::ResponseAction
BinanceGetCoinNetworksFunction::Run() {
if (!IsBinanceAPIAvailable(browser_context())) {
return RespondNow(Error("Not available in Tor/incognito/guest profile"));
}

auto* service = GetBinanceService(browser_context());
bool balance_success = service->GetCoinNetworks(
base::BindOnce(
&BinanceGetCoinNetworksFunction::OnGetCoinNetworks,
this));

if (!balance_success) {
return RespondNow(Error("Could not send request to get coin networks"));
}

return RespondLater();
}

void BinanceGetCoinNetworksFunction::OnGetCoinNetworks(
const std::map<std::string, std::string>& networks) {
auto coin_networks = std::make_unique<base::Value>(
base::Value::Type::DICTIONARY);

for (const auto& network : networks) {
coin_networks->SetStringKey(network.first, network.second);
}

Respond(OneArgument(std::move(coin_networks)));
}

} // namespace api
} // namespace extensions
15 changes: 14 additions & 1 deletion browser/extensions/api/binance_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class BinanceGetDepositInfoFunction :
protected:
~BinanceGetDepositInfoFunction() override {}
void OnGetDepositInfo(const std::string& deposit_address,
const std::string& deposit_url,
const std::string& deposit_tag,
bool success);

ResponseAction Run() override;
Expand Down Expand Up @@ -162,6 +162,19 @@ class BinanceRevokeTokenFunction :
ResponseAction Run() override;
};

class BinanceGetCoinNetworksFunction :
public ExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("binance.getCoinNetworks", UNKNOWN)

protected:
~BinanceGetCoinNetworksFunction() override {}
void OnGetCoinNetworks(
const std::map<std::string, std::string>& networks);

ResponseAction Run() override;
};

} // namespace api
} // namespace extensions

Expand Down
1 change: 1 addition & 0 deletions browser/ui/webui/brave_webui_source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ void CustomizeWebUIHTMLSource(const std::string &name,
{ "binanceWidgetSearch", IDS_BINANCE_WIDGET_SEARCH },
{ "binanceWidgetAddressUnavailable", IDS_BINANCE_WIDGET_ADDRESS_UNAVAILABLE }, // NOLINT
{ "binanceWidgetDepositAddress", IDS_BINANCE_WIDGET_DEPOSIT_ADDRESS },
{ "binanceWidgetDepositMemo", IDS_BINANCE_WIDGET_DEPOSIT_MEMO },
{ "binanceWidgetConfirmConversion", IDS_BINANCE_WIDGET_CONFIRM_CONVERSION }, // NOLINT
{ "binanceWidgetConvert", IDS_BINANCE_WIDGET_CONVERT },
{ "binanceWidgetRate", IDS_BINANCE_WIDGET_RATE },
Expand Down
24 changes: 23 additions & 1 deletion common/extensions/api/binance.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@
{
"type": "string",
"name": "symbol"
},
{
"type": "string",
"name": "tickerNetwork"
}, {
"type": "function",
"name": "callback",
Expand All @@ -207,7 +211,7 @@
"type": "string"
},
{
"name": "depositURL",
"name": "depositTag",
"type": "string"
}
]
Expand Down Expand Up @@ -272,6 +276,24 @@
]
}
]
},
{
"name": "getCoinNetworks",
"type": "function",
"description": "Retrieves the primary networks for Binance assets",
"parameters": [
{
"type": "function",
"name": "callback",
"parameters": [
{
"name": "networks",
"type": "object",
"additionalProperties": { "type": "string" }
}
]
}
]
}
],
"types": [
Expand Down
83 changes: 74 additions & 9 deletions components/binance/browser/binance_json_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ bool BinanceJSONParser::GetTickerVolumeFromJSON(
// "success": true
// }
bool BinanceJSONParser::GetDepositInfoFromJSON(
const std::string& json, std::string *address, std::string *url) {
const std::string& json, std::string *address, std::string *tag) {
DCHECK(address);
DCHECK(url);
DCHECK(tag);

base::JSONReader::ValueWithError value_with_error =
base::JSONReader::ReadAndReturnValueWithError(
Expand All @@ -241,16 +241,11 @@ bool BinanceJSONParser::GetDepositInfoFromJSON(
return false;
}

std::string deposit_url;
std::string deposit_address;

if (!data_dict->GetString("url", &deposit_url) ||
!data_dict->GetString("address", &deposit_address)) {
if (!data_dict->GetString("tag", tag) ||
!data_dict->GetString("address", address)) {
return false;
}

*url = deposit_url;
*address = deposit_address;
return true;
}

Expand Down Expand Up @@ -419,3 +414,73 @@ bool BinanceJSONParser::RevokeTokenFromJSON(

return true;
}

// static
// Response Format:
// {
// "code": "000000",
// "message": null,
// "messageDetail": null,
// "success": true,
// "data": [
// {
// "coin": "CTR",
// "networkList": [
// {
// "coin": "CTR",
// "network": "ETH"
// }
// ]
// }
// ]
// }
//
bool BinanceJSONParser::GetCoinNetworksFromJSON(
const std::string& json, std::map<std::string, std::string>* networks) {
if (!networks) {
return false;
}

base::JSONReader::ValueWithError value_with_error =
base::JSONReader::ReadAndReturnValueWithError(
json, base::JSONParserOptions::JSON_PARSE_RFC);
base::Optional<base::Value>& records_v = value_with_error.value;

if (!records_v) {
LOG(ERROR) << "Invalid response, could not parse JSON, JSON is: " << json;
return false;
}

const base::Value* data_arr = records_v->FindKey("data");
if (!data_arr || !data_arr->is_list()) {
return false;
}

for (const base::Value &coin : data_arr->GetList()) {
const base::Value* coin_name = coin.FindKey("coin");
if (!coin_name || !coin_name->is_string()) {
return false;
}

const base::Value* network_list = coin.FindKey("networkList");
if (!network_list || !network_list->is_list()) {
return false;
}

for (const base::Value &network : network_list->GetList()) {
const base::Value* network_name = network.FindKey("network");
const base::Value* is_default = network.FindKey("isDefault");
const bool default_valid =
is_default && is_default->is_bool() && is_default->GetBool();
const bool network_name_valid =
network_name && network_name->is_string();

if (default_valid && network_name_valid) {
networks->insert({coin_name->GetString(), network_name->GetString()});
break;
}
}
}

return true;
}
6 changes: 4 additions & 2 deletions components/binance/browser/binance_json_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class BinanceJSONParser {
std::string* symbol_pair_volume);
static bool GetDepositInfoFromJSON(const std::string& json,
std::string* address,
std::string *url);
std::string* tag);
static bool GetQuoteInfoFromJSON(const std::string& json,
std::string* quote_id,
std::string* quote_price,
Expand All @@ -34,9 +34,11 @@ class BinanceJSONParser {
std::string *error_message,
bool* success_status);
static bool GetConvertAssetsFromJSON(const std::string& json,
std::map<std::string, std::vector<std::string>>* assets);
std::map<std::string, std::vector<std::string>>* assets);
static bool RevokeTokenFromJSON(const std::string& json,
bool* success_status);
static bool GetCoinNetworksFromJSON(const std::string& json,
std::map<std::string, std::string>* networks);
};

#endif // BRAVE_COMPONENTS_BINANCE_BROWSER_BINANCE_JSON_PARSER_H_
92 changes: 79 additions & 13 deletions components/binance/browser/binance_json_parser_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@

namespace {

std::string GetBalanceFromAssets(
const std::map<std::string, std::string>& balances,
const std::string& asset) {
std::string balance;
std::string GetValueFromStringMap(
const std::map<std::string, std::string>& map,
const std::string& key) {
std::string value;
std::map<std::string, std::string>::const_iterator it =
balances.find(asset);
if (it != balances.end()) {
balance = it->second;
map.find(key);
if (it != map.end()) {
value = it->second;
}
return balance;
return value;
}

typedef testing::Test BinanceJSONParserTest;
Expand Down Expand Up @@ -50,8 +50,8 @@ TEST_F(BinanceJSONParserTest, GetAccountBalancesFromJSON) {
]
})", &balances));

std::string bnb_balance = GetBalanceFromAssets(balances, "BNB");
std::string btc_balance = GetBalanceFromAssets(balances, "BTC");
std::string bnb_balance = GetValueFromStringMap(balances, "BNB");
std::string btc_balance = GetValueFromStringMap(balances, "BTC");
ASSERT_EQ(bnb_balance, "10114.00000000");
ASSERT_EQ(btc_balance, "2.45000000");
}
Expand Down Expand Up @@ -105,20 +105,40 @@ TEST_F(BinanceJSONParserTest, GetTickerVolumeFromJSON) {

TEST_F(BinanceJSONParserTest, GetDepositInfoFromJSON) {
std::string deposit_address;
std::string deposit_url;
std::string deposit_tag;
ASSERT_TRUE(BinanceJSONParser::GetDepositInfoFromJSON(R"(
{
"code": "0000",
"message": "null",
"data": {
"coin": "BTC",
"tag": "",
"address": "112tfsHDk6Yk8PbNnTVkv7yPox4aWYYDtW",
"url": "https://btc.com/112tfsHDk6Yk8PbNnTVkv7yPox4aWYYDtW",
"time": 1566366289000
}
})", &deposit_address, &deposit_url));
})", &deposit_address, &deposit_tag));
ASSERT_EQ(deposit_address, "112tfsHDk6Yk8PbNnTVkv7yPox4aWYYDtW");
ASSERT_EQ(deposit_url, "https://btc.com/112tfsHDk6Yk8PbNnTVkv7yPox4aWYYDtW");
ASSERT_EQ(deposit_tag, "");
}

TEST_F(BinanceJSONParserTest, GetDepositInfoFromJSONWithTag) {
std::string deposit_address;
std::string deposit_tag;
ASSERT_TRUE(BinanceJSONParser::GetDepositInfoFromJSON(R"(
{
"code": "0000",
"message": "null",
"data": {
"coin": "EOS",
"tag": "0902394082",
"address": "binancecleos",
"url": "",
"time": 1566366289000
}
})", &deposit_address, &deposit_tag));
ASSERT_EQ(deposit_address, "binancecleos");
ASSERT_EQ(deposit_tag, "0902394082");
}

TEST_F(BinanceJSONParserTest, GetQuoteInfoFromJSON) {
Expand Down Expand Up @@ -211,4 +231,50 @@ TEST_F(BinanceJSONParserTest, RevokeTokenFromJSONFail) {
ASSERT_FALSE(success);
}

TEST_F(BinanceJSONParserTest, GetCoinNetworksFromJSON) {
std::map<std::string, std::string> networks;
ASSERT_TRUE(BinanceJSONParser::GetCoinNetworksFromJSON(R"(
{
"code": "000000",
"message": null,
"data": [
{
"coin": "BAT",
"networkList": [
{
"coin": "BAT",
"network": "ETH",
"isDefault": true
},
{
"coin": "BAT",
"network": "BNB",
"isDefault": false
}
]
},
{
"coin": "GAS",
"networkList": [
{
"coin": "GAS",
"network": "BTC",
"isDefault": false
},
{
"coin": "GAS",
"network": "NEO",
"isDefault": true
}
]
}
]
})", &networks));

std::string bat_network = GetValueFromStringMap(networks, "BAT");
std::string gas_network = GetValueFromStringMap(networks, "GAS");
ASSERT_EQ(bat_network, "ETH");
ASSERT_EQ(gas_network, "NEO");
}

} // namespace
Loading

0 comments on commit c56b020

Please sign in to comment.