Skip to content

Commit

Permalink
Gas tracker page (#1524)
Browse files Browse the repository at this point in the history
* add custom headers to API resource

* refactoring

* page title

* chart

* gas prices snippet

* GasPrice component

* add ENV for gas units

* dark theme and other tweaks

* tests

* add base and priority fee

* [skip ci] small fiat values

* change behavior of the variable

* update tooltip layout

* refactor gas info tooltip

* refactor GasPrice component

* fix logic and deploy demo for eth mainnet

* tests

* remove link from anchor

* [skip ci] rollback ENVs for demo

* review fixes

* fix tests
  • Loading branch information
tom2drum authored Feb 20, 2024
1 parent 5c2d06f commit 7c69314
Show file tree
Hide file tree
Showing 90 changed files with 1,231 additions and 265 deletions.
37 changes: 37 additions & 0 deletions configs/app/features/gasTracker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Feature } from './types';
import { GAS_UNITS } from 'types/client/gasTracker';
import type { GasUnit } from 'types/client/gasTracker';

import { getEnvValue, parseEnvJson } from '../utils';

const isDisabled = getEnvValue('NEXT_PUBLIC_GAS_TRACKER_ENABLED') === 'false';

const units = ((): Array<GasUnit> => {
const envValue = getEnvValue('NEXT_PUBLIC_GAS_TRACKER_UNITS');
if (!envValue) {
return [ 'usd', 'gwei' ];
}

const units = parseEnvJson<Array<GasUnit>>(envValue)?.filter((type) => GAS_UNITS.includes(type)) || [];

return units;
})();

const title = 'Gas tracker';

const config: Feature<{ units: Array<GasUnit> }> = (() => {
if (!isDisabled && units.length > 0) {
return Object.freeze({
title,
isEnabled: true,
units,
});
}

return Object.freeze({
title,
isEnabled: false,
});
})();

export default config;
1 change: 1 addition & 0 deletions configs/app/features/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { default as beaconChain } from './beaconChain';
export { default as bridgedTokens } from './bridgedTokens';
export { default as blockchainInteraction } from './blockchainInteraction';
export { default as csvExport } from './csvExport';
export { default as gasTracker } from './gasTracker';
export { default as googleAnalytics } from './googleAnalytics';
export { default as graphqlApiDocs } from './graphqlApiDocs';
export { default as growthBook } from './growthBook';
Expand Down
1 change: 0 additions & 1 deletion configs/app/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const UI = Object.freeze({
background: getEnvValue('NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND') || HOMEPAGE_PLATE_BACKGROUND_DEFAULT,
textColor: getEnvValue('NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR') || 'white',
},
showGasTracker: getEnvValue('NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER') === 'false' ? false : true,
showAvgBlockTime: getEnvValue('NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME') === 'false' ? false : true,
},
views,
Expand Down
1 change: 0 additions & 1 deletion configs/envs/.env.jest
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ NEXT_PUBLIC_API_BASE_PATH=/
## homepage
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs','coin_price','market_cap']
NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME=true
NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER=true
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND=
## sidebar
NEXT_PUBLIC_NETWORK_LOGO=
Expand Down
1 change: 0 additions & 1 deletion configs/envs/.env.pw
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ NEXT_PUBLIC_API_BASE_PATH=/
## homepage
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs','coin_price','market_cap']
NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME=true
NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER=true
## sidebar
## footer
NEXT_PUBLIC_GIT_TAG=v1.0.11
Expand Down
5 changes: 4 additions & 1 deletion deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import type { AdButlerConfig } from '../../../types/client/adButlerConfig';
import { SUPPORTED_AD_TEXT_PROVIDERS, SUPPORTED_AD_BANNER_PROVIDERS } from '../../../types/client/adProviders';
import type { AdTextProviders, AdBannerProviders } from '../../../types/client/adProviders';
import type { ContractCodeIde } from '../../../types/client/contract';
import { GAS_UNITS } from '../../../types/client/gasTracker';
import type { GasUnit } from '../../../types/client/gasTracker';
import type { MarketplaceAppOverview } from '../../../types/client/marketplace';
import { NAVIGATION_LINK_IDS } from '../../../types/client/navigation-items';
import type { NavItemExternal, NavigationLinkId } from '../../../types/client/navigation-items';
Expand Down Expand Up @@ -390,7 +392,6 @@ const schema = yup
.of(yup.string<ChainIndicatorId>().oneOf([ 'daily_txs', 'coin_price', 'market_cap', 'tvl' ])),
NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR: yup.string(),
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND: yup.string(),
NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER: yup.boolean(),
NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME: yup.boolean(),

// b. sidebar
Expand Down Expand Up @@ -493,6 +494,8 @@ const schema = yup
NEXT_PUBLIC_HAS_USER_OPS: yup.boolean(),
NEXT_PUBLIC_SWAP_BUTTON_URL: yup.string(),
NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE: yup.string<ValidatorsChainType>().oneOf(VALIDATORS_CHAIN_TYPE),
NEXT_PUBLIC_GAS_TRACKER_ENABLED: yup.boolean(),
NEXT_PUBLIC_GAS_TRACKER_UNITS: yup.array().transform(replaceQuotes).json().of(yup.string<GasUnit>().oneOf(GAS_UNITS)),

// 6. External services envs
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: yup.string(),
Expand Down
3 changes: 2 additions & 1 deletion deploy/tools/envs-validator/test/.env.base
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ NEXT_PUBLIC_HIDE_INDEXING_ALERT_INT_TXS=false
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR='#fff'
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND='rgb(255, 145, 0)'
NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER=true
NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME=true
NEXT_PUBLIC_GAS_TRACKER_ENABLED=true
NEXT_PUBLIC_GAS_TRACKER_UNITS=['gwei']
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_MAINTENANCE_ALERT_MESSAGE='<a href="#">Hello</a>'
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
Expand Down
1 change: 1 addition & 0 deletions docs/DEPRECATED_ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
| NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK | `boolean` | Set to true for zkevm L2 solutions | Required | - | `true` | v1.24.0 | Replaced by NEXT_PUBLIC_ROLLUP_TYPE |
| NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL | `string` | URL for optimistic L2 -> L1 withdrawals | Required | - | `https://app.optimism.io/bridge/withdraw` | v1.24.0 | Renamed to NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL |
| NEXT_PUBLIC_L1_BASE_URL | `string` | Blockscout base URL for L1 network | Required | - | `'http://eth-goerli.blockscout.com'` | v1.24.0 | Renamed to NEXT_PUBLIC_ROLLUP_L1_BASE_URL |
| NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER | `boolean` | Set to false if network doesn't have gas tracker | - | `true` | `false` | v1.25.0 | Replaced by NEXT_PUBLIC_GAS_TRACKER_ENABLED |
13 changes: 12 additions & 1 deletion docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will
- [Misc](ENVS.md#misc)
- [App features](ENVS.md#app-features)
- [My account](ENVS.md#my-account)
- [Gas tracker](ENVS.md#gas-tracker)
- [Address verification](ENVS.md#address-verification-in-my-account) in "My account"
- [Blockchain interaction](ENVS.md#blockchain-interaction-writing-to-contract-etc) (writing to contract, etc.)
- [Banner ads](ENVS.md#banner-ads)
Expand Down Expand Up @@ -108,7 +109,6 @@ Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will
| NEXT_PUBLIC_HOMEPAGE_CHARTS | `Array<'daily_txs' \| 'coin_price' \| 'market_cap' \| 'tvl'>` | List of charts displayed on the home page | - | - | `['daily_txs','coin_price','market_cap']` |
| NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR | `string` | Text color of the hero plate on the homepage (escape "#" symbol if you use HEX color codes or use rgba-value instead) | - | `white` | `\#DCFE76` |
| NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND | `string` | Background css value for hero plate on the homepage (escape "#" symbol if you use HEX color codes or use rgba-value instead) | - | `radial-gradient(103.03% 103.03% at 0% 0%, rgba(183, 148, 244, 0.8) 0%, rgba(0, 163, 196, 0.8) 100%), var(--chakra-colors-blue-400)` | `radial-gradient(at 15% 86%, hsla(350,65%,70%,1) 0px, transparent 50%)` \| `no-repeat bottom 20% right 0px/100% url(https://placekitten/1400/200)` |
| NEXT_PUBLIC_HOMEPAGE_SHOW_GAS_TRACKER | `boolean` | Set to false if network doesn't have gas tracker | - | `true` | `false` |
| NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME | `boolean` | Set to false if average block time is useless for the network | - | `true` | `false` |

&nbsp;
Expand Down Expand Up @@ -302,6 +302,17 @@ Settings for meta tags and OG tags

&nbsp;

### Gas tracker

This feature is **enabled by default**. To switch it off pass `NEXT_PUBLIC_GAS_TRACKER_ENABLED=false`.

| Variable | Type| Description | Compulsoriness | Default value | Example value |
| --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_GAS_TRACKER_ENABLED | `boolean` | Set to true to enable "Gas tracker" in the app | Required | `true` | `false` |
| NEXT_PUBLIC_GAS_TRACKER_UNITS | Array<`usd` \| `gwei`> | Array of units for displaying gas prices on the Gas Tracker page, in the stats snippet on the Home page, and in the top bar. The first value in the array will take priority over the second one in all mentioned views. If only one value is provided, gas prices will be displayed only in that unit. | - | `[ 'usd', 'gwei' ]` | `[ 'gwei' ]` |

&nbsp;

### Address verification in "My account"

*Note* all ENV variables required for [My account](ENVS.md#my-account) feature should be passed alongside the following ones:
Expand Down
3 changes: 3 additions & 0 deletions icons/gas_xl.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions icons/rocket_xl.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 14 additions & 8 deletions lib/api/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export interface ApiResource {
basePath?: string;
pathParams?: Array<string>;
needAuth?: boolean; // for external APIs which require authentication
headers?: RequestInit['headers'];
}

export const SORTING_FIELDS = [ 'sort', 'order' ];
Expand Down Expand Up @@ -184,7 +185,7 @@ export const RESOURCES = {
needAuth: true,
},

// STATS
// STATS MICROSERVICE API
stats_counters: {
path: '/api/v1/counters',
endpoint: getFeaturePayload(config.features.stats)?.api.endpoint,
Expand Down Expand Up @@ -513,16 +514,21 @@ export const RESOURCES = {
filterFields: [],
},

// HOMEPAGE
homepage_stats: {
// APP STATS
stats: {
path: '/api/v2/stats',
headers: {
'updated-gas-oracle': 'true',
},
},
homepage_chart_txs: {
stats_charts_txs: {
path: '/api/v2/stats/charts/transactions',
},
homepage_chart_market: {
stats_charts_market: {
path: '/api/v2/stats/charts/market',
},

// HOMEPAGE
homepage_blocks: {
path: '/api/v2/main-page/blocks',
},
Expand Down Expand Up @@ -750,9 +756,9 @@ Q extends 'watchlist' ? WatchlistResponse :
Q extends 'verified_addresses' ? VerifiedAddressResponse :
Q extends 'token_info_applications_config' ? TokenInfoApplicationConfig :
Q extends 'token_info_applications' ? TokenInfoApplications :
Q extends 'homepage_stats' ? HomeStats :
Q extends 'homepage_chart_txs' ? ChartTransactionResponse :
Q extends 'homepage_chart_market' ? ChartMarketResponse :
Q extends 'stats' ? HomeStats :
Q extends 'stats_charts_txs' ? ChartTransactionResponse :
Q extends 'stats_charts_market' ? ChartMarketResponse :
Q extends 'homepage_blocks' ? Array<Block> :
Q extends 'homepage_txs' ? Array<Transaction> :
Q extends 'homepage_txs_watchlist' ? Array<Transaction> :
Expand Down
1 change: 1 addition & 0 deletions lib/api/useApiFetch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default function useApiFetch() {
'x-endpoint': resource.endpoint && isNeedProxy() ? resource.endpoint : undefined,
Authorization: resource.endpoint && resource.needAuth ? apiToken : undefined,
'x-csrf-token': withBody && csrfToken ? csrfToken : undefined,
...resource.headers,
...fetchParams?.headers,
}, Boolean) as HeadersInit;

Expand Down
7 changes: 6 additions & 1 deletion lib/hooks/useNavItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,13 @@ export default function useNavItems(): ReturnType {
nextRoute: { pathname: '/contract-verification' as const },
isActive: pathname.startsWith('/contract-verification'),
},
config.features.gasTracker.isEnabled && {
text: 'Gas tracker',
nextRoute: { pathname: '/gas-tracker' as const },
isActive: pathname.startsWith('/gas-tracker'),
},
...config.UI.sidebar.otherLinks,
],
].filter(Boolean),
},
].filter(Boolean);

Expand Down
1 change: 1 addition & 0 deletions lib/metadata/getPageOgType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
'/name-domains': 'Root page',
'/name-domains/[name]': 'Regular page',
'/validators': 'Root page',
'/gas-tracker': 'Root page',

// service routes, added only to make typescript happy
'/login': 'Regular page',
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/templates/description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/name-domains': DEFAULT_TEMPLATE,
'/name-domains/[name]': DEFAULT_TEMPLATE,
'/validators': DEFAULT_TEMPLATE,
'/gas-tracker': DEFAULT_TEMPLATE,

// service routes, added only to make typescript happy
'/login': DEFAULT_TEMPLATE,
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/templates/title.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/name-domains': 'domains search and resolve',
'/name-domains/[name]': '%name% domain details',
'/validators': 'validators list',
'/gas-tracker': 'gas tracker',

// service routes, added only to make typescript happy
'/login': 'login',
Expand Down
1 change: 1 addition & 0 deletions lib/mixpanel/getPageType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
'/name-domains': 'Domains search and resolve',
'/name-domains/[name]': 'Domain details',
'/validators': 'Validators list',
'/gas-tracker': 'Gas tracker',

// service routes, added only to make typescript happy
'/login': 'Login',
Expand Down
45 changes: 33 additions & 12 deletions mocks/stats/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
import type { HomeStats } from 'types/api/stats';
import _mapValues from 'lodash/mapValues';

export const base: HomeStats = {
export const base = {
average_block_time: 6212.0,
coin_price: '0.00199678',
coin_price_change_percentage: -7.42,
gas_prices: {
average: {
fiat_price: '1.01',
price: 20.41,
time: 12283,
fiat_price: '1.39',
price: 23.75,
time: 12030.25,
base_fee: 2.22222,
priority_fee: 12.424242,
},
fast: {
fiat_price: '1.26',
price: 25.47,
time: 9321,
fiat_price: '1.74',
price: 29.72,
time: 8763.25,
base_fee: 4.44444,
priority_fee: 22.242424,
},
slow: {
fiat_price: '0.97',
price: 19.55,
time: 24543,
fiat_price: '1.35',
price: 23.04,
time: 20100.25,
base_fee: 1.11111,
priority_fee: 7.8909,
},
},
gas_price_updated_at: '2022-11-11T11:09:49.051171Z',
Expand All @@ -35,7 +41,22 @@ export const base: HomeStats = {
tvl: '1767425.102766552',
};

export const withBtcLocked: HomeStats = {
export const withBtcLocked = {
...base,
rootstock_locked_btc: '3337493406696977561374',
};

export const withoutFiatPrices = {
...base,
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, fiat_price: null }) : null),
};

export const withoutGweiPrices = {
...base,
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null }) : null),
};

export const withoutBothPrices = {
...base,
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null, fiat_price: null }) : null),
};
Loading

0 comments on commit 7c69314

Please sign in to comment.