Skip to content

Commit

Permalink
Parse image parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
yrliou committed Dec 10, 2021
1 parent 7899ea8 commit a843947
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 17 deletions.
1 change: 1 addition & 0 deletions components/brave_wallet/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ static_library("common") {
":mojom__generator",
"//base",
"//brave/third_party/ethash",
"//url",
]
}

Expand Down
18 changes: 13 additions & 5 deletions components/brave_wallet/common/eth_request_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "brave/components/brave_wallet/common/eth_address.h"
#include "brave/components/brave_wallet/common/hex_utils.h"
#include "brave/components/brave_wallet/common/web3_provider_constants.h"
#include "url/gurl.h"

namespace {

Expand Down Expand Up @@ -472,12 +473,19 @@ bool ParseWalletWatchAssetParams(const std::string& json,
return false;
}

// TODO(jocelyn): Parse image URL to be the logo URL once we supports
// downloading an icon from a remote URL.
std::string logo;
const std::string* image = options_dict->FindStringKey("image");
if (image) {
GURL url = GURL(*image);
if (url.is_valid() && (url.SchemeIsHTTPOrHTTPS() ||
base::StartsWith(*image, "data:image/"))) {
logo = url.spec();
}
}

*token = mojom::ERCToken::New(eth_addr.ToChecksumAddress(),
*symbol /* name */, "" /* logo */, true, false,
*symbol, decimals, true, "");
*token =
mojom::ERCToken::New(eth_addr.ToChecksumAddress(), *symbol /* name */,
logo, true, false, *symbol, decimals, true, "");

return true;
}
Expand Down
74 changes: 68 additions & 6 deletions components/brave_wallet/common/eth_request_helper_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,6 @@ TEST(EthRequestHelperUnitTest, ParseEthSignTypedDataParams) {
}

TEST(EthRequestHelperUnitTest, ParseWalletWatchAssetParams) {
// Image will be ignored currently.
std::string json = R"({
"id": "1",
"jsonrpc": "2.0",
Expand All @@ -567,23 +566,24 @@ TEST(EthRequestHelperUnitTest, ParseWalletWatchAssetParams) {
"address": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF",
"symbol": "BAT",
"decimals": 18,
"image": "https://test.png"
"image": "https://test.com/test.png"
},
"type": "ERC20"
}
})";

mojom::ERCTokenPtr expected_token = mojom::ERCToken::New(
"0x0D8775F648430679A709E98d2b0Cb6250d2887EF", "BAT",
"" /* logo is empty because image parameter is currently ignored. */,
true, false, "BAT", 18, true, "");
"https://test.com/test.png", true, false, "BAT", 18, true, "");

mojom::ERCTokenPtr token;
std::string error_message;
EXPECT_TRUE(ParseWalletWatchAssetParams(json, &token, &error_message));
EXPECT_EQ(token, expected_token);
EXPECT_TRUE(error_message.empty());

expected_token->logo = "";

// Test optional image and non-checksum address.
json = R"({
"id": "1",
Expand Down Expand Up @@ -760,8 +760,7 @@ TEST(EthRequestHelperUnitTest, ParseWalletWatchAssetParams) {
"options": {
"address": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF",
"symbol": "BAT",
"decimals": 18,
"image": "https://test.png"
"decimals": 18
},
"type": "ERC20"
}]
Expand All @@ -770,6 +769,69 @@ TEST(EthRequestHelperUnitTest, ParseWalletWatchAssetParams) {
EXPECT_TRUE(ParseWalletWatchAssetParams(json, &token, &error_message));
EXPECT_EQ(token, expected_token);
EXPECT_TRUE(error_message.empty());

// Test image parameter
json = R"({
"id": "1",
"jsonrpc": "2.0",
"method": "wallet_watchAsset",
"params": {
"options": {
"address": "0x0d8775f648430679a709e98d2b0cb6250d2887ef",
"symbol": "BAT",
"decimals": 18,
"image": "http://test.com/test.png"
},
"type": "ERC20"
}
})";
expected_token->logo = "http://test.com/test.png";
EXPECT_TRUE(ParseWalletWatchAssetParams(json, &token, &error_message));
EXPECT_EQ(token, expected_token);
EXPECT_TRUE(error_message.empty());

json = R"({
"id": "1",
"jsonrpc": "2.0",
"method": "wallet_watchAsset",
"params": {
"options": {
"address": "0x0d8775f648430679a709e98d2b0cb6250d2887ef",
"symbol": "BAT",
"decimals": 18,
"image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
},
"type": "ERC20"
}
})";
expected_token->logo =
"data:image/"
"png;base64,"
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3"
"A0FDAAAAAElFTkSuQmCC";
EXPECT_TRUE(ParseWalletWatchAssetParams(json, &token, &error_message));
EXPECT_EQ(token, expected_token);
EXPECT_TRUE(error_message.empty());

// Invalid image parameter will have empty logo string.
json = R"({
"id": "1",
"jsonrpc": "2.0",
"method": "wallet_watchAsset",
"params": {
"options": {
"address": "0x0d8775f648430679a709e98d2b0cb6250d2887ef",
"symbol": "BAT",
"decimals": 18,
"image": "test.png"
},
"type": "ERC20"
}
})";
expected_token->logo = "";
EXPECT_TRUE(ParseWalletWatchAssetParams(json, &token, &error_message));
EXPECT_EQ(token, expected_token);
EXPECT_TRUE(error_message.empty());
}

} // namespace brave_wallet
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import { ERCToken } from '../../../constants/types'
import { IconWrapper, PlaceholderText } from './style'
import { stripERC20TokenImageURL } from '../../../utils/string-utils'
import { stripERC20TokenImageURL, isRemoteImageURL } from '../../../utils/string-utils'
import { background } from 'ethereum-blockies'
import { ETH } from '../../../options/asset-options'

Expand Down Expand Up @@ -29,7 +29,7 @@ function withPlaceholderIcon (WrappedComponent: React.ComponentType<any>, config
return null
}
const tokenImageURL = stripERC20TokenImageURL(selectedAsset?.logo)
const checkIconURL = selectedAsset?.symbol !== 'ETH' && (tokenImageURL === '' || tokenImageURL?.startsWith('http'))
const checkIconURL = selectedAsset?.symbol !== 'ETH' && (tokenImageURL === '' || isRemoteImageURL(tokenImageURL))

const bg = React.useMemo(() => {
if (checkIconURL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { getLocale } from '../../../common/locale'

import getWalletPanelApiProxy from '../wallet_panel_api_proxy'
import { HardwareVendor } from '../../common/api/hardware_keyrings'
import { isRemoteImageURL } from '../../utils/string-utils'

const handler = new AsyncActionHandler()

Expand Down Expand Up @@ -107,11 +108,8 @@ async function getPendingAddSuggestTokenRequest () {
const requests =
(await braveWalletService.getPendingAddSuggestTokenRequests()).requests
if (requests && requests.length) {
// Currently it will only be non-empty if the logo info is coming from us,
// either from user asset list or the ERC token registry, re-map the logo
// url to show the icon correctly in the add suggest token UI.
const logo = requests[0].token.logo
if (logo !== '') {
if (logo !== '' && !isRemoteImageURL(logo)) {
requests[0].token.logo = `chrome://erc-token-images/${logo}`
}
return requests[0]
Expand Down
23 changes: 23 additions & 0 deletions components/brave_wallet_ui/utils/string-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { isRemoteImageURL } from './string-utils'

describe('Checking URL is remote image or not', () => {
test('HTTP URL should return true', () => {
expect(isRemoteImageURL('http://test.com/test.png')).toEqual(true)
})

test('HTTPS URL should return true', () => {
expect(isRemoteImageURL('https://test.com/test.png')).toEqual(true)
})

test('Data URL image should return true', () => {
expect(isRemoteImageURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC')).toEqual(true)
})

test('local path should return false', () => {
expect(isRemoteImageURL('bat.png')).toEqual(false)
})

test('undefined input should return undefined', () => {
expect(isRemoteImageURL(undefined)).toEqual(undefined)
})
})
3 changes: 3 additions & 0 deletions components/brave_wallet_ui/utils/string-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ export const stripERC20TokenImageURL = (url?: string) =>
export const toProperCase = (value: string) =>
value.replace(/\w\S*/g,
(txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase())

export const isRemoteImageURL = (url?: string) =>
url?.startsWith('http://') || url?.startsWith('https://') || url?.startsWith('data:image/')

0 comments on commit a843947

Please sign in to comment.