Merge pull request #550 from 0xProject/feature/website/crypto-compare-prices
Grab wallet price information by token symbol
This commit is contained in:
@@ -461,16 +461,16 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
|
||||
);
|
||||
balanceAndAllowanceTupleByAddress[tokenAddress] = balanceAndAllowanceTuple;
|
||||
}
|
||||
const pricesByAddress = await this._getPricesByAddressAsync(tokenAddresses);
|
||||
const priceByAddress = await this._getPriceByAddressAsync(tokenAddresses);
|
||||
const trackedTokenStateByAddress = _.reduce(
|
||||
tokenAddresses,
|
||||
(acc, address) => {
|
||||
const [balance, allowance] = balanceAndAllowanceTupleByAddress[address];
|
||||
const price = pricesByAddress[address];
|
||||
const priceIfExists = _.get(priceByAddress, address);
|
||||
acc[address] = {
|
||||
balance,
|
||||
allowance,
|
||||
price,
|
||||
price: priceIfExists,
|
||||
isLoaded: true,
|
||||
};
|
||||
return acc;
|
||||
@@ -487,16 +487,29 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
|
||||
private async _refetchTokenStateAsync(tokenAddress: string) {
|
||||
await this._fetchBalancesAndAllowancesAsync([tokenAddress]);
|
||||
}
|
||||
private async _getPricesByAddressAsync(tokenAddresses: string[]): Promise<ItemByAddress<BigNumber>> {
|
||||
private async _getPriceByAddressAsync(tokenAddresses: string[]): Promise<ItemByAddress<BigNumber>> {
|
||||
if (_.isEmpty(tokenAddresses)) {
|
||||
return {};
|
||||
}
|
||||
// for each input token address, search for the corresponding symbol in this.props.tokenByAddress, if it exists
|
||||
// create a mapping from existing symbols -> address
|
||||
const tokenAddressBySymbol: { [symbol: string]: string } = {};
|
||||
_.each(tokenAddresses, address => {
|
||||
const tokenIfExists = _.get(this.props.tokenByAddress, address);
|
||||
if (!_.isUndefined(tokenIfExists)) {
|
||||
const symbol = tokenIfExists.symbol;
|
||||
tokenAddressBySymbol[symbol] = address;
|
||||
}
|
||||
});
|
||||
const tokenSymbols = _.keys(tokenAddressBySymbol);
|
||||
try {
|
||||
const websiteBackendPriceInfos = await backendClient.getPriceInfosAsync(tokenAddresses);
|
||||
const addresses = _.map(websiteBackendPriceInfos, info => info.address);
|
||||
const prices = _.map(websiteBackendPriceInfos, info => new BigNumber(info.price));
|
||||
const pricesByAddress = _.zipObject(addresses, prices);
|
||||
return pricesByAddress;
|
||||
const priceBySymbol = await backendClient.getPriceInfoAsync(tokenSymbols);
|
||||
const priceByAddress = _.mapKeys(priceBySymbol, (value, symbol) => _.get(tokenAddressBySymbol, symbol));
|
||||
const result = _.mapValues(priceByAddress, price => {
|
||||
const priceBigNumber = new BigNumber(price);
|
||||
return priceBigNumber;
|
||||
});
|
||||
return result;
|
||||
} catch (err) {
|
||||
return {};
|
||||
}
|
||||
|
@@ -509,8 +509,7 @@ export interface WebsiteBackendRelayerInfo {
|
||||
}
|
||||
|
||||
export interface WebsiteBackendPriceInfo {
|
||||
price: string;
|
||||
address: string;
|
||||
[symbol: string]: string;
|
||||
}
|
||||
|
||||
export interface WebsiteBackendGasInfo {
|
||||
|
@@ -1,16 +1,8 @@
|
||||
import { BigNumber, logUtils } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
import * as queryString from 'query-string';
|
||||
|
||||
import {
|
||||
ArticlesBySection,
|
||||
ItemByAddress,
|
||||
WebsiteBackendGasInfo,
|
||||
WebsiteBackendPriceInfo,
|
||||
WebsiteBackendRelayerInfo,
|
||||
} from 'ts/types';
|
||||
import { ArticlesBySection, WebsiteBackendGasInfo, WebsiteBackendPriceInfo, WebsiteBackendRelayerInfo } from 'ts/types';
|
||||
import { configs } from 'ts/utils/configs';
|
||||
import { errorReporter } from 'ts/utils/error_reporter';
|
||||
import { fetchUtils } from 'ts/utils/fetch_utils';
|
||||
|
||||
const ETH_GAS_STATION_ENDPOINT = '/eth_gas_station';
|
||||
const PRICES_ENDPOINT = '/prices';
|
||||
@@ -19,52 +11,26 @@ const WIKI_ENDPOINT = '/wiki';
|
||||
|
||||
export const backendClient = {
|
||||
async getGasInfoAsync(): Promise<WebsiteBackendGasInfo> {
|
||||
const result = await requestAsync(ETH_GAS_STATION_ENDPOINT);
|
||||
const result = await fetchUtils.requestAsync(configs.BACKEND_BASE_URL, ETH_GAS_STATION_ENDPOINT);
|
||||
return result;
|
||||
},
|
||||
async getPriceInfosAsync(tokenAddresses: string[]): Promise<WebsiteBackendPriceInfo[]> {
|
||||
if (_.isEmpty(tokenAddresses)) {
|
||||
return [];
|
||||
async getPriceInfoAsync(tokenSymbols: string[]): Promise<WebsiteBackendPriceInfo> {
|
||||
if (_.isEmpty(tokenSymbols)) {
|
||||
return {};
|
||||
}
|
||||
const joinedTokenAddresses = tokenAddresses.join(',');
|
||||
const joinedTokenSymbols = tokenSymbols.join(',');
|
||||
const queryParams = {
|
||||
tokens: joinedTokenAddresses,
|
||||
tokens: joinedTokenSymbols,
|
||||
};
|
||||
const result = await requestAsync(PRICES_ENDPOINT, queryParams);
|
||||
const result = await fetchUtils.requestAsync(configs.BACKEND_BASE_URL, PRICES_ENDPOINT, queryParams);
|
||||
return result;
|
||||
},
|
||||
async getRelayerInfosAsync(): Promise<WebsiteBackendRelayerInfo[]> {
|
||||
const result = await requestAsync(RELAYERS_ENDPOINT);
|
||||
const result = await fetchUtils.requestAsync(configs.BACKEND_BASE_URL, RELAYERS_ENDPOINT);
|
||||
return result;
|
||||
},
|
||||
async getWikiArticlesBySectionAsync(): Promise<ArticlesBySection> {
|
||||
const result = await requestAsync(WIKI_ENDPOINT);
|
||||
const result = await fetchUtils.requestAsync(configs.BACKEND_BASE_URL, WIKI_ENDPOINT);
|
||||
return result;
|
||||
},
|
||||
};
|
||||
|
||||
async function requestAsync(endpoint: string, queryParams?: object): Promise<any> {
|
||||
const query = queryStringFromQueryParams(queryParams);
|
||||
const url = `${configs.BACKEND_BASE_URL}${endpoint}${query}`;
|
||||
const response = await fetch(url);
|
||||
if (response.status !== 200) {
|
||||
const errorText = `Error requesting url: ${url}, ${response.status}: ${response.statusText}`;
|
||||
logUtils.log(errorText);
|
||||
const error = Error(errorText);
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
errorReporter.reportAsync(error);
|
||||
throw error;
|
||||
}
|
||||
const result = await response.json();
|
||||
return result;
|
||||
}
|
||||
|
||||
function queryStringFromQueryParams(queryParams?: object): string {
|
||||
// if params are undefined or empty, return an empty string
|
||||
if (_.isUndefined(queryParams) || _.isEmpty(queryParams)) {
|
||||
return '';
|
||||
}
|
||||
// stringify the formatted object
|
||||
const stringifiedParams = queryString.stringify(queryParams);
|
||||
return `?${stringifiedParams}`;
|
||||
}
|
||||
|
33
packages/website/ts/utils/fetch_utils.ts
Normal file
33
packages/website/ts/utils/fetch_utils.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { logUtils } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
import * as queryString from 'query-string';
|
||||
|
||||
import { errorReporter } from 'ts/utils/error_reporter';
|
||||
|
||||
export const fetchUtils = {
|
||||
async requestAsync(baseUrl: string, path: string, queryParams?: object): Promise<any> {
|
||||
const query = queryStringFromQueryParams(queryParams);
|
||||
const url = `${baseUrl}${path}${query}`;
|
||||
const response = await fetch(url);
|
||||
if (response.status !== 200) {
|
||||
const errorText = `Error requesting url: ${url}, ${response.status}: ${response.statusText}`;
|
||||
logUtils.log(errorText);
|
||||
const error = Error(errorText);
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
errorReporter.reportAsync(error);
|
||||
throw error;
|
||||
}
|
||||
const result = await response.json();
|
||||
return result;
|
||||
},
|
||||
};
|
||||
|
||||
function queryStringFromQueryParams(queryParams?: object): string {
|
||||
// if params are undefined or empty, return an empty string
|
||||
if (_.isUndefined(queryParams) || _.isEmpty(queryParams)) {
|
||||
return '';
|
||||
}
|
||||
// stringify the formatted object
|
||||
const stringifiedParams = queryString.stringify(queryParams);
|
||||
return `?${stringifiedParams}`;
|
||||
}
|
12
yarn.lock
12
yarn.lock
@@ -11448,9 +11448,9 @@ web3-net@1.0.0-beta.33:
|
||||
web3-core-method "1.0.0-beta.33"
|
||||
web3-utils "1.0.0-beta.33"
|
||||
|
||||
web3-provider-engine@^13.0.1, web3-provider-engine@^13.6.5:
|
||||
version "13.6.6"
|
||||
resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.6.6.tgz#7d8972ffcd31e103bd2ce8a521b1b7da08cb173f"
|
||||
web3-provider-engine@^13.3.2:
|
||||
version "13.8.0"
|
||||
resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz#4c7c1ad2af5f1fe10343b8a65495879a2f9c00df"
|
||||
dependencies:
|
||||
async "^2.5.0"
|
||||
clone "^2.0.0"
|
||||
@@ -11472,9 +11472,9 @@ web3-provider-engine@^13.0.1, web3-provider-engine@^13.6.5:
|
||||
xhr "^2.2.0"
|
||||
xtend "^4.0.1"
|
||||
|
||||
web3-provider-engine@^13.3.2:
|
||||
version "13.8.0"
|
||||
resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz#4c7c1ad2af5f1fe10343b8a65495879a2f9c00df"
|
||||
web3-provider-engine@^13.6.5:
|
||||
version "13.6.6"
|
||||
resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.6.6.tgz#7d8972ffcd31e103bd2ce8a521b1b7da08cb173f"
|
||||
dependencies:
|
||||
async "^2.5.0"
|
||||
clone "^2.0.0"
|
||||
|
Reference in New Issue
Block a user