Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
a8ce6ef
refactor widgets on home page
tom2drum Sep 10, 2025
c6ece2f
coming soon placeholder component
tom2drum Sep 11, 2025
08525c0
top accounts page
tom2drum Sep 11, 2025
8ee128c
contract data
tom2drum Sep 11, 2025
70fcad1
address ERC-20 tokens list
tom2drum Sep 15, 2025
8b33067
chain filter for address ERC-20 tokens
tom2drum Sep 15, 2025
cd2ba7c
token select for address detailed view
tom2drum Sep 15, 2025
563c8d1
address details fields
tom2drum Sep 17, 2025
502254d
tokens table
tom2drum Sep 18, 2025
0b4410e
stats widgets on home page
tom2drum Sep 18, 2025
f277e5b
chain indicators graph on the home page
tom2drum Sep 22, 2025
b633cc1
quick search
tom2drum Sep 22, 2025
48d94d0
search results all tab
tom2drum Sep 23, 2025
21306b9
tabs and chain select on search results page
tom2drum Sep 23, 2025
4692c10
search results mobile view
tom2drum Sep 24, 2025
e97316f
add contract info to search and address details
tom2drum Sep 24, 2025
24287e7
Merge branch 'main' of github.com:blockscout/frontend into tom2drum/i…
tom2drum Sep 29, 2025
f96bb27
add text filter for tokens and search improvements
tom2drum Sep 30, 2025
9766671
load all results inside tab on search results page
tom2drum Sep 30, 2025
1cab993
token balance info
tom2drum Oct 1, 2025
bcf6cee
add support for domains in the full search
tom2drum Oct 1, 2025
739b884
Multichain explorer
tom2drum Oct 1, 2025
6bdb9dc
add envs validator for multichain
tom2drum Oct 2, 2025
c2966bf
add some tests
tom2drum Oct 2, 2025
31df27a
Merge branch 'main' of github.com:blockscout/frontend into tom2drum/i…
tom2drum Oct 2, 2025
2f5c909
fix search bar on search results page on mobile
tom2drum Oct 2, 2025
04e236d
home stats fixes
tom2drum Oct 2, 2025
cd98dca
fix ts
tom2drum Oct 2, 2025
8784eb4
optimize amount of queries on address page
tom2drum Oct 3, 2025
75f6395
add more contract info on address page
tom2drum Oct 3, 2025
8482419
add enter key hint to search input
tom2drum Oct 3, 2025
66ef2fc
fix tests
tom2drum Oct 3, 2025
c892daf
fix test
tom2drum Oct 3, 2025
9bb5242
update bg.primary css-variable on color theme change
tom2drum Oct 6, 2025
1a9df29
sitemap for multichain
tom2drum Oct 6, 2025
0b91cce
txs page: render first tab if blob tab is not available on the chain
tom2drum Oct 7, 2025
8e38c6a
filter out in active chains from chain select on address page and use…
tom2drum Oct 7, 2025
5a9aa3f
add chain icon to advanced filter table
tom2drum Oct 7, 2025
b2ead9a
fix tooltip on entity with shield
tom2drum Oct 7, 2025
5cae1c6
fix ts
tom2drum Oct 7, 2025
1561bca
Merge branch 'main' of github.com:blockscout/frontend into tom2drum/i…
tom2drum Oct 9, 2025
1b7b90b
show contract implementations
tom2drum Oct 9, 2025
f39502f
fixes
tom2drum Oct 9, 2025
2a30426
Merge branch 'main' of github.com:blockscout/frontend into tom2drum/i…
tom2drum Oct 21, 2025
061c003
add chain icon to all lists
tom2drum Oct 22, 2025
24ec49f
refactor zetachain chains config type
tom2drum Oct 22, 2025
950ad90
use chain id as primary option instead of chain slug
tom2drum Oct 22, 2025
0fcdcd3
refactor chain config type for multichain and essential dapps
tom2drum Oct 23, 2025
6b7396b
refactor chain icon and chain select
tom2drum Oct 23, 2025
1483b89
rename chain-slug in chain_slug
tom2drum Oct 23, 2025
c635f1a
change default radius of chain icon and update screenshots for multic…
tom2drum Oct 23, 2025
de14c93
change conditions for "isContract" and "isVerified"
tom2drum Oct 23, 2025
debed54
test fixes
tom2drum Oct 23, 2025
b608c8d
make shield optional for external chain entities
tom2drum Oct 24, 2025
06696e4
add chain icon to approvals lists
tom2drum Oct 24, 2025
365b219
add stats page for multichain
tom2drum Oct 29, 2025
2e639d1
Merge branch 'main' of github.com:blockscout/frontend into tom2drum/i…
tom2drum Oct 29, 2025
9fa7526
add chain postfix to chart .png and .csv assets name
tom2drum Oct 29, 2025
4f6c924
fix tests
tom2drum Oct 30, 2025
c069d68
sync verified contracts language filter and fix loading state in the …
tom2drum Nov 3, 2025
c7055de
fix sol2uml diagram and csv export
tom2drum Nov 5, 2025
444164c
regcred from helmfile for review
nzenchik Nov 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
26 changes: 21 additions & 5 deletions configs/app/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export interface ApiPropsFull extends ApiPropsBase {

const generalApi = (() => {
const apiHost = getEnvValue('NEXT_PUBLIC_API_HOST');
if (!apiHost) {
return;
}

const apiSchema = getEnvValue('NEXT_PUBLIC_API_PROTOCOL') || 'https';
const apiPort = getEnvValue('NEXT_PUBLIC_API_PORT');
const apiEndpoint = [
Expand Down Expand Up @@ -101,9 +105,10 @@ const rewardsApi = (() => {
});
})();

const multichainApi = (() => {
const multichainAggregatorApi = (() => {
const apiHost = getEnvValue('NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST');
if (!apiHost) {
const cluster = getEnvValue('NEXT_PUBLIC_MULTICHAIN_CLUSTER');
if (!apiHost || !cluster) {
return;
}

Expand All @@ -113,12 +118,22 @@ const multichainApi = (() => {
return Object.freeze({
endpoint: apiHost,
socketEndpoint: `wss://${ url.host }`,
basePath: stripTrailingSlash(getEnvValue('NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_BASE_PATH') || ''),
basePath: `/api/v1/clusters/${ cluster }`,
});
} catch (error) {
return;
}
})();

const multichainStatsApi = (() => {
const apiHost = getEnvValue('NEXT_PUBLIC_MULTICHAIN_STATS_API_HOST');
if (!apiHost) {
return;
}

return Object.freeze({
endpoint: apiHost,
});
})();

const statsApi = (() => {
Expand Down Expand Up @@ -197,7 +212,7 @@ const zetachainApi = (() => {
})();

export type Apis = {
general: ApiPropsFull;
general: ApiPropsFull | undefined;
} & Partial<Record<Exclude<ApiName, 'general'>, ApiPropsBase>>;

const apis: Apis = Object.freeze({
Expand All @@ -207,7 +222,8 @@ const apis: Apis = Object.freeze({
clusters: clustersApi,
contractInfo: contractInfoApi,
metadata: metadataApi,
multichain: multichainApi,
multichainAggregator: multichainAggregatorApi,
multichainStats: multichainStatsApi,
rewards: rewardsApi,
stats: statsApi,
tac: tacApi,
Expand Down
13 changes: 10 additions & 3 deletions configs/app/features/opSuperchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ import type { Feature } from './types';
import apis from '../apis';
import { getEnvValue } from '../utils';

const isEnabled = getEnvValue('NEXT_PUBLIC_OP_SUPERCHAIN_ENABLED') === 'true';
const isEnabled = getEnvValue('NEXT_PUBLIC_MULTICHAIN_ENABLED') === 'true';
const cluster = getEnvValue('NEXT_PUBLIC_MULTICHAIN_CLUSTER');

// The feature was initially implemented for OP Superchain interop cluster
// but later the project was abandoned by Optimism team.
// Now it serves mainly for demo purposes of multichain explorer possible functionalities.
// So for now I have kept all naming in the code as it was initially done
// and later it could be changed when specific multichain cluster will be implemented.
const title = 'OP Superchain interop explorer';

const config: Feature<{ }> = (() => {
if (apis.multichain && isEnabled) {
const config: Feature<{ cluster: string }> = (() => {
if (apis.multichainAggregator && apis.multichainStats && isEnabled && cluster) {
return Object.freeze({
title,
isEnabled: true,
cluster,
});
}

Expand Down
3 changes: 2 additions & 1 deletion configs/app/features/stats.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { Feature } from './types';

import apis from '../apis';
import opSuperchain from './opSuperchain';

const title = 'Blockchain statistics';

const config: Feature<{}> = (() => {
if (apis.stats) {
if (apis.stats || opSuperchain.isEnabled) {
return Object.freeze({
title,
isEnabled: true,
Expand Down
25 changes: 7 additions & 18 deletions configs/envs/.env.optimism_superchain
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,18 @@ NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development

# Instance ENVs
# TODO @tom2drum make these envs optional for multichain (adjust docs)
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=localhost
NEXT_PUBLIC_API_PORT=3001
NEXT_PUBLIC_API_PROTOCOL=http
NEXT_PUBLIC_NETWORK_ID=10

# TODO @tom2drum New ENVs (add to docs)
NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST=https://multichain-aggregator.k8s-dev.blockscout.com
NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_BASE_PATH=/api/v1/clusters/interop
NEXT_PUBLIC_OP_SUPERCHAIN_ENABLED=true
NEXT_PUBLIC_MULTICHAIN_STATS_API_HOST=http://multichain-search-stats.k8s-dev.blockscout.com
NEXT_PUBLIC_MULTICHAIN_ENABLED=true
NEXT_PUBLIC_MULTICHAIN_CLUSTER=interop

# TODO @tom2drum remove this
SKIP_ENVS_VALIDATION=true
SKIP_ENVS_VALIDATION=false

NEXT_PUBLIC_API_SPEC_URL=none
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs','coin_price','market_cap']
NEXT_PUBLIC_HOMEPAGE_STATS=['total_txs','wallet_addresses']
NEXT_PUBLIC_API_DOCS_TABS=[]
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/optimism-mainnet.json
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/optimism.json
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=none
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs', 'coin_price', 'market_cap', 'secondary_coin_price']
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['linear-gradient(90deg, rgb(232, 52, 53) 0%, rgb(139, 28, 232) 100%)'],'text_color':['rgb(255, 255, 255)']}
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism-superchain.svg
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism-superchain.svg
Expand All @@ -39,7 +29,6 @@ NEXT_PUBLIC_NETWORK_NAME=OP Superchain
NEXT_PUBLIC_NETWORK_SHORT_NAME=OP Superchain
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/optimism-mainnet.png
NEXT_PUBLIC_GAS_TRACKER_ENABLED=false
NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS=['eth_rpc_api','rpc_api']
NEXT_PUBLIC_HIDE_INDEXING_ALERT_BLOCKS=true
NEXT_PUBLIC_HIDE_INDEXING_ALERT_INT_TXS=true
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=false
Expand Down
4 changes: 3 additions & 1 deletion configs/envs/.env.pw
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@ NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=http://localhost:3006
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=http://localhost:3007
NEXT_PUBLIC_NAME_SERVICE_API_HOST=http://localhost:3008
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=http://localhost:3009
NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST=http://localhost:3010
NEXT_PUBLIC_TAC_OPERATION_LIFECYCLE_API_HOST=http://localhost:3100
NEXT_PUBLIC_USER_OPS_INDEXER_API_HOST=http://localhost:3110
NEXT_PUBLIC_ZETACHAIN_SERVICE_API_HOST=http://localhost:3111
NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST=http://localhost:3012
NEXT_PUBLIC_MULTICHAIN_CLUSTER=test
NEXT_PUBLIC_MULTICHAIN_STATS_API_HOST=http://localhost:3013
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY=xxx
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=xxx
NEXT_PUBLIC_VIEWS_ADDRESS_FORMAT=['base16','bech32']
Expand Down
4 changes: 2 additions & 2 deletions configs/essential-dapps-chains/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { MultichainConfig } from 'types/multichain';
import type { EssentialDappsChainConfig } from 'types/client/marketplace';

import config from 'configs/app';
import { isBrowser } from 'toolkit/utils/isBrowser';

const marketplaceFeature = config.features.marketplace;

const essentialDappsChains: () => MultichainConfig | undefined = () => {
const essentialDappsChains: () => { chains: Array<EssentialDappsChainConfig> } | undefined = () => {
if (!marketplaceFeature.isEnabled || !marketplaceFeature.essentialDapps) {
return;
}
Expand Down
28 changes: 0 additions & 28 deletions deploy/helmfile.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,6 @@ repositories:
---
releases:
# Deploy review L2
- name: reg-secret
chart: bedag/raw
namespace: review-l2-{{ requiredEnv "GITHUB_REF_NAME_SLUG" }}
labels:
app: review-l2-{{ requiredEnv "GITHUB_REF_NAME_SLUG" }}
values:
- resources:
- apiVersion: v1
data:
.dockerconfigjson: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/dockerRegistryCreds
kind: Secret
metadata:
name: regcred
type: kubernetes.io/dockerconfigjson
- name: bs-stack
chart: blockscout/blockscout-stack
version: 1.*.*
Expand All @@ -41,20 +27,6 @@ releases:
- global:
env: "review"
# Deploy review
- name: reg-secret
chart: bedag/raw
namespace: review-{{ requiredEnv "GITHUB_REF_NAME_SLUG" }}
labels:
app: review-{{ requiredEnv "GITHUB_REF_NAME_SLUG" }}
values:
- resources:
- apiVersion: v1
data:
.dockerconfigjson: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/dockerRegistryCreds
kind: Secret
metadata:
name: regcred
type: kubernetes.io/dockerconfigjson
- name: bs-stack
chart: blockscout/blockscout-stack
version: 1.*.*
Expand Down
8 changes: 7 additions & 1 deletion deploy/tools/envs-validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { ValidationError } from 'yup';

import { buildExternalAssetFilePath } from '../../../configs/app/utils';
import schema from './schema';
import schemaMultichain from './schema_multichain';

const silent = process.argv.includes('--silent');

Expand Down Expand Up @@ -51,7 +52,12 @@ async function validateEnvs(appEnvs: Record<string, string>) {
}
}

await schema.validate(appEnvs, { stripUnknown: false, abortEarly: false });
if (appEnvs.NEXT_PUBLIC_MULTICHAIN_ENABLED === 'true') {
await schemaMultichain.validate(appEnvs, { stripUnknown: false, abortEarly: false });
} else {
await schema.validate(appEnvs, { stripUnknown: false, abortEarly: false });
}

!silent && console.log('👍 All good!');
} catch (_error) {
if (typeof _error === 'object' && _error !== null && 'errors' in _error) {
Expand Down
Loading
Loading