Skip to content

Commit

Permalink
pools pages
Browse files Browse the repository at this point in the history
  • Loading branch information
isstuev committed Dec 13, 2024
1 parent f672d23 commit 975df8c
Show file tree
Hide file tree
Showing 50 changed files with 1,085 additions and 127 deletions.
1 change: 1 addition & 0 deletions configs/app/features/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export { default as mixpanel } from './mixpanel';
export { default as mudFramework } from './mudFramework';
export { default as multichainButton } from './multichainButton';
export { default as nameService } from './nameService';
export { default as pools } from './pools';
export { default as publicTagsSubmission } from './publicTagsSubmission';
export { default as restApiDocs } from './restApiDocs';
export { default as rewards } from './rewards';
Expand Down
28 changes: 28 additions & 0 deletions configs/app/features/pools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Feature } from './types';

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

const contractInfoApiHost = getEnvValue('NEXT_PUBLIC_CONTRACT_INFO_API_HOST');
const dexPoolsEnabled = getEnvValue('NEXT_PUBLIC_DEX_POOLS_ENABLED');

const title = 'Pools';

const config: Feature<{ api: { endpoint: string; basePath: string } }> = (() => {
if (contractInfoApiHost && dexPoolsEnabled) {
return Object.freeze({
title,
isEnabled: true,
api: {
endpoint: contractInfoApiHost,
basePath: '',
},
});
}

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

export default config;
2 changes: 1 addition & 1 deletion configs/envs/.env.eth
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=eth.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info-test.k8s-dev.blockscout.com
NEXT_PUBLIC_DATA_AVAILABILITY_ENABLED=true
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swapscout','icon':'swap','dappId':'swapscout'},{'text':'Disperse','icon':'txn_batches_slim','dappId':'smol'},{'text':'Payment link','icon':'payment_link','dappId':'peanut-protocol'},{'text':'Get gas','icon':'gas','dappId':'smol-refuel'}]
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/eth.json
Expand Down
5 changes: 3 additions & 2 deletions configs/envs/.env.eth_sepolia
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=eth-sepolia.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info-test.k8s-dev.blockscout.com
NEXT_PUBLIC_DATA_AVAILABILITY_ENABLED=true
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swap','icon':'swap','dappId':'cow-swap'},{'text':'Payment link','icon':'payment_link','dappId':'peanut-protocol'}]
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/eth-sepolia.json
Expand Down Expand Up @@ -68,4 +68,5 @@ NEXT_PUBLIC_STATS_API_HOST=https://stats-sepolia.k8s.blockscout.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=noves
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_XSTAR_SCORE_URL=https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm?utm_source=blockscout&utm_medium=address
NEXT_PUBLIC_XSTAR_SCORE_URL=https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm?utm_source=blockscout&utm_medium=addres
NEXT_PUBLIC_DEX_POOLS_ENABLED=true
10 changes: 10 additions & 0 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,16 @@ const schema = yup
value => value === undefined,
),
}),
NEXT_PUBLIC_DEX_POOLS_ENABLED: yup.boolean()
.when('NEXT_PUBLIC_CONTRACT_INFO_API_HOST', {
is: (value: string) => Boolean(value),
then: (schema) => schema,
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_DEX_POOLS_ENABLED can only be used with NEXT_PUBLIC_CONTRACT_INFO_API_HOST',
value => value === undefined,
),
}),
NEXT_PUBLIC_SAVE_ON_GAS_ENABLED: yup.boolean(),
NEXT_PUBLIC_ADDRESS_USERNAME_TAG: yup
.mixed()
Expand Down
10 changes: 10 additions & 0 deletions docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will
- [Get gas button](ENVS.md#get-gas-button)
- [Save on gas with GasHawk](ENVS.md#save-on-gas-with-gashawk)
- [Rewards service API](ENVS.md#rewards-service-api)
- [DEX pools](ENVS.md#dex-pools)
- [3rd party services configuration](ENVS.md#external-services-configuration)

&nbsp;
Expand Down Expand Up @@ -841,6 +842,15 @@ This feature enables Blockscout Merits program. It requires that the [My account
| --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_REWARDS_SERVICE_API_HOST | `string` | API URL | - | - | `https://example.com` | v1.36.0+ |

&nbsp;

### DEX pools

| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_DEX_POOLS_ENABLED | `boolean` | Set to true to enable the feature | Required | - | `true` | v1.37.0+ |
| NEXT_PUBLIC_CONTRACT_INFO_API_HOST | `string` | Contract Info API endpoint url | Required | - | `https://contracts-info.services.blockscout.com` | v1.0.x+ |

## External services configuration

### Google ReCaptcha
Expand Down
4 changes: 4 additions & 0 deletions icons/dex-tracker.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: 21 additions & 1 deletion lib/api/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ import type {
OptimismL2BatchTxs,
OptimismL2BatchBlocks,
} from 'types/api/optimisticL2';
import type { Pool, PoolsResponse } from 'types/api/pools';
import type { RawTracesResponse } from 'types/api/rawTrace';
import type {
RewardsConfigResponse,
Expand Down Expand Up @@ -1089,6 +1090,22 @@ export const RESOURCES = {
pathParams: [ 'hash' as const ],
},

// POOLS
pools: {
path: '/api/v1/chains/:chainId/pools',
pathParams: [ 'chainId' as const ],
filterFields: [ 'query' as const ],
endpoint: getFeaturePayload(config.features.pools)?.api.endpoint,
basePath: getFeaturePayload(config.features.pools)?.api.basePath,
},

pool: {
path: '/api/v1/chains/:chainId/pools/:hash',
pathParams: [ 'chainId' as const, 'hash' as const ],
endpoint: getFeaturePayload(config.features.pools)?.api.endpoint,
basePath: getFeaturePayload(config.features.pools)?.api.basePath,
},

// CONFIGS
config_backend_version: {
path: '/api/v2/config/backend-version',
Expand Down Expand Up @@ -1183,7 +1200,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | 'block_election_reward
'watchlist' | 'private_tags_address' | 'private_tags_tx' |
'domains_lookup' | 'addresses_lookup' | 'user_ops' | 'validators_stability' | 'validators_blackfort' | 'noves_address_history' |
'token_transfers_all' | 'scroll_l2_txn_batches' | 'scroll_l2_txn_batch_txs' | 'scroll_l2_txn_batch_blocks' |
'scroll_l2_deposits' | 'scroll_l2_withdrawals';
'scroll_l2_deposits' | 'scroll_l2_withdrawals' | 'pools';

export type PaginatedResponse<Q extends PaginatedResources> = ResourcePayload<Q>;

Expand Down Expand Up @@ -1375,6 +1392,8 @@ Q extends 'scroll_l2_deposits' ? ScrollL2MessagesResponse :
Q extends 'scroll_l2_deposits_count' ? number :
Q extends 'scroll_l2_withdrawals' ? ScrollL2MessagesResponse :
Q extends 'scroll_l2_withdrawals_count' ? number :
Q extends 'pools' ? PoolsResponse :
Q extends 'pool' ? Pool :
never;
/* eslint-enable @stylistic/indent */

Expand Down Expand Up @@ -1410,6 +1429,7 @@ Q extends 'validators_stability' ? ValidatorsStabilityFilters :
Q extends 'address_mud_tables' ? AddressMudTablesFilter :
Q extends 'address_mud_records' ? AddressMudRecordsFilter :
Q extends 'token_transfers_all' ? TokenTransferFilters :
Q extends 'pools' ? { query: string } :
never;
/* eslint-enable @stylistic/indent */

Expand Down
8 changes: 7 additions & 1 deletion lib/hooks/useNavItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,13 @@ export default function useNavItems(): ReturnType {
icon: 'token-transfers',
isActive: pathname === '/token-transfers',
},
];
config.features.pools.isEnabled && {
text: 'DEX tracker',
nextRoute: { pathname: '/pools' as const },
icon: 'dex-tracker',
isActive: pathname === '/pools' || pathname.startsWith('/pool/'),
},
].filter(Boolean);

const apiNavItems: Array<NavItem> = [
config.features.restApiDocs.isEnabled ? {
Expand Down
2 changes: 2 additions & 0 deletions lib/metadata/getPageOgType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
'/gas-tracker': 'Root page',
'/mud-worlds': 'Root page',
'/token-transfers': 'Root page',
'/pools': 'Root page',
'/pools/[hash]': 'Regular page',

// service routes, added only to make typescript happy
'/login': 'Regular page',
Expand Down
2 changes: 2 additions & 0 deletions lib/metadata/templates/description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/gas-tracker': 'Explore real-time %network_title% gas fees with Blockscout\'s advanced gas fee tracker. Get accurate %network_gwei% estimates and track transaction costs live.',
'/mud-worlds': DEFAULT_TEMPLATE,
'/token-transfers': DEFAULT_TEMPLATE,
'/pools': DEFAULT_TEMPLATE,
'/pools/[hash]': DEFAULT_TEMPLATE,

// service routes, added only to make typescript happy
'/login': DEFAULT_TEMPLATE,
Expand Down
2 changes: 2 additions & 0 deletions lib/metadata/templates/title.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/gas-tracker': 'Track %network_name% gas fees in %network_gwei%',
'/mud-worlds': '%network_name% MUD worlds list',
'/token-transfers': '%network_name% token transfers',
'/pools': '%network_name% DEX pools',
'/pools/[hash]': '%network_name% pool details',

// service routes, added only to make typescript happy
'/login': '%network_name% login',
Expand Down
2 changes: 2 additions & 0 deletions lib/mixpanel/getPageType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
'/gas-tracker': 'Gas tracker',
'/mud-worlds': 'MUD worlds',
'/token-transfers': 'Token transfers',
'/pools': 'DEX pools',
'/pools/[hash]': 'Pool details',

// service routes, added only to make typescript happy
'/login': 'Login',
Expand Down
23 changes: 23 additions & 0 deletions mocks/pools/pool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Pool } from 'types/api/pools';

export const base: Pool = {
contract_address: '0x06da0fd433c1a5d7a4faa01111c044910a184553',
chain_id: '1',
base_token_address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
base_token_symbol: 'USDT',
base_token_icon_url: 'https://localhost:3000/utia.jpg',
quote_token_address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
quote_token_symbol: 'WETH',
quote_token_icon_url: 'https://localhost:3000/secondary_utia.jpg',
fully_diluted_valuation_usd: '75486579078',
market_cap_usd: '139312819076.195',
liquidity: '2099941.2238',
dex: { id: 'sushiswap', name: 'SushiSwap' },
coin_gecko_terminal_url: 'https://www.geckoterminal.com/eth/pools/0x06da0fd433c1a5d7a4faa01111c044910a184553',
};

export const noIcons: Pool = {
...base,
base_token_icon_url: null,
quote_token_icon_url: null,
};
10 changes: 10 additions & 0 deletions nextjs/getServerSideProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,13 @@ export const mud: GetServerSideProps<Props> = async(context) => {

return base(context);
};

export const pools: GetServerSideProps<Props> = async(context) => {
if (!config.features.pools.isEnabled) {
return {
notFound: true,
};
}

return base(context);
};
2 changes: 2 additions & 0 deletions nextjs/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ declare module "nextjs-routes" {
| DynamicRoute<"/op/[hash]", { "hash": string }>
| StaticRoute<"/ops">
| StaticRoute<"/output-roots">
| DynamicRoute<"/pools/[hash]", { "hash": string }>
| StaticRoute<"/pools">
| StaticRoute<"/public-tags/submit">
| StaticRoute<"/search-results">
| StaticRoute<"/sprite">
Expand Down
20 changes: 20 additions & 0 deletions pages/pools/[hash].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';

import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';

const Pool = dynamic(() => import('ui/pages/Pool'), { ssr: false });

const Page: NextPage<Props> = (props: Props) => {
return (
<PageNextJs pathname="/pools/[hash]" query={ props.query }>
<Pool/>
</PageNextJs>
);
};

export default Page;

export { pools as getServerSideProps } from 'nextjs/getServerSideProps';
19 changes: 19 additions & 0 deletions pages/pools/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';

import PageNextJs from 'nextjs/PageNextJs';

const Pools = dynamic(() => import('ui/pages/Pools'), { ssr: false });

const Page: NextPage = () => {
return (
<PageNextJs pathname="/name-domains">
<Pools/>
</PageNextJs>
);
};

export default Page;

export { pools as getServerSideProps } from 'nextjs/getServerSideProps';
1 change: 1 addition & 0 deletions public/icons/name.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
| "copy"
| "cross"
| "delete"
| "dex-tracker"
| "docs"
| "donate"
| "dots"
Expand Down
Binary file added public/static/gecko_terminal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions stubs/pools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const POOL = {
contract_address: '0x6a1041865b76d1dc33da0257582591227c57832c',
chain_id: '1',
base_token_address: '0xf63e309818e4ea13782678ce6c31c1234fa61809',
base_token_symbol: 'JANET',
base_token_icon_url: null,
quote_token_address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
quote_token_symbol: 'WETH',
quote_token_icon_url: 'https://coin-images.coingecko.com/coins/images/2518/small/weth.png?1696503332',
fully_diluted_valuation_usd: '15211385',
market_cap_usd: '15211385',
liquidity: '394101.2428',
dex: { id: 'uniswap_v2', name: 'Uniswap V2' },
coin_gecko_terminal_url: 'https://www.geckoterminal.com/eth/pools/0x6a1041865b76d1dc33da0257582591227c57832c',
};
26 changes: 26 additions & 0 deletions types/api/pools.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export type PoolsResponse = {
items: Array<Pool>;
next_page_params: {
page_token: string;
page_size: number;
} | null;
};

export type Pool = {
contract_address: string;
chain_id: string;
base_token_address: string;
base_token_symbol: string;
base_token_icon_url: string | null;
quote_token_address: string;
quote_token_symbol: string;
quote_token_icon_url: string | null;
fully_diluted_valuation_usd: string;
market_cap_usd: string;
liquidity: string;
dex: {
id: string;
name: string;
};
coin_gecko_terminal_url: string;
};
Loading

0 comments on commit 975df8c

Please sign in to comment.