Skip to content
This repository was archived by the owner on Jan 9, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3fbbcd2
Bump brace-expansion from 1.1.11 to 1.1.12 in /deploy/tools/affected-…
dependabot[bot] Jun 25, 2025
be7b9fc
allow toaster to render custom description
tom2drum Jun 26, 2025
fdd6ade
Encode the address hash for links to the TON chain (#2813)
tom2drum Jun 27, 2025
84663f2
Support redirects for known address discrepancies (#2799)
tom2drum Jun 30, 2025
ff04dc8
Celo: support L2 epochs (#2784)
tom2drum Jun 30, 2025
2b2332c
Icons in footer links (#2809)
tom2drum Jun 30, 2025
5feb561
Metadata: send address to fetchers once visited (#2814)
tom2drum Jun 30, 2025
a01299b
Display and handle `status` field in smart contract view (#2807)
tom2drum Jul 1, 2025
843a047
OP Superchain Explorer: MVP (#2786)
tom2drum Jul 3, 2025
ad61f74
Change persistence of Mixpanel config (#2823)
tom2drum Jul 4, 2025
54a35a8
Changes in ReCaptcha behavior (#2829)
tom2drum Jul 4, 2025
a2b9c41
Address widgets (#2788)
maxaleks Jul 4, 2025
1a5f0e6
Change txs socket alert text (#2822)
isstuev Jul 4, 2025
0280f80
Inconsistent cursor when hovering over NavLinkGroup (#2831)
isstuev Jul 7, 2025
baeedfe
bump graphiql from 2.2.0 to 4.1.2
maxaleks Jul 10, 2025
045aea9
remove bots from monitoring
isstuev Jul 7, 2025
5c2218f
remove csv-export from sitemap
isstuev Jul 10, 2025
376627f
fix widgets label loading state
maxaleks Jul 11, 2025
3319c12
Update useQueryClientConfig.tsx
maxaleks Jul 17, 2025
f4a2c6d
fix empty value
maxaleks Jul 17, 2025
ce4bf4c
fix refetching
maxaleks Jul 17, 2025
b1ca426
Fix to run yarn dev locally
isaozler May 14, 2025
129615b
Chain selection feature added
isaozler May 22, 2025
a3a4d60
Env + dep changes
isaozler May 30, 2025
c3a629d
Global setup, TopBar, SideBar init
isaozler Jun 24, 2025
1c037ac
WIP - before rebase
isaozler Jun 24, 2025
f136c43
Changes & fixes except gas tracker page - WIP
isaozler Jun 24, 2025
13936e0
Env setup
isaozler Jun 24, 2025
b836e91
chore: autoformat publish-image.yml
alber70g Jun 25, 2025
ff14358
chore: update yarn.lock
alber70g Jun 25, 2025
44a91aa
chore: introduce our own publish image
alber70g Jun 25, 2025
c01aece
fix: typescript types
alber70g Jun 25, 2025
68b8186
fix: typings envs-validator
alber70g Jun 25, 2025
f434894
chore: add workflow permissions.packages: write for publish to GHCR
alber70g Jun 25, 2025
e7ef456
fix: used wrong image name
alber70g Jun 25, 2025
266418e
Refactored the network and chain selection to only use a single file …
isaozler Jun 26, 2025
22bbc7f
fix: chain selection
javadkh2 Jun 26, 2025
49660e9
fix: use custome chains
javadkh2 Jun 26, 2025
20f77cc
fix import
javadkh2 Jun 26, 2025
4a89a61
revert date changes
javadkh2 Jun 26, 2025
031edc2
fix url
javadkh2 Jun 26, 2025
b9258dd
use testnet backend in dev mode
javadkh2 Jul 3, 2025
7f2d0a7
Minor updates to UI/UX (#12)
isaozler Jul 3, 2025
04c91ad
fix: env
javadkh2 Jul 16, 2025
5568a97
Fix/UI changes mobile desktop monospace (#15)
isaozler Jul 21, 2025
c572c45
Sync latest tag v2.2.1
isaozler Jul 21, 2025
dfc984c
Merge branch 'main' into sync/v2.2.1
isaozler Jul 21, 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
  •  
  •  
  •  
24 changes: 24 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile

- name: Generate Chakra types
if: steps.cache-node-modules.outputs.cache-hit == 'true'
run: yarn chakra:typegen

- name: Run ESLint
run: echo "skip lint:eslint for now"

Expand Down Expand Up @@ -77,6 +81,10 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile

- name: Generate Chakra types
if: steps.cache-node-modules.outputs.cache-hit == 'true'
run: yarn chakra:typegen

- name: Install package dependencies
run: |
cd ./toolkit/package
Expand Down Expand Up @@ -136,6 +144,10 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile

- name: Generate Chakra types
if: steps.cache-node-modules.outputs.cache-hit == 'true'
run: yarn chakra:typegen

- name: Install script dependencies
run: cd ./deploy/tools/envs-validator && yarn --frozen-lockfile

Expand Down Expand Up @@ -175,6 +187,10 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile

- name: Generate Chakra types
if: steps.cache-node-modules.outputs.cache-hit == 'true'
run: yarn chakra:typegen

- name: Run Jest
run: yarn test:jest ${{ github.event_name == 'pull_request' && '--changedSince=origin/main' || '' }} --passWithNoTests

Expand Down Expand Up @@ -207,6 +223,10 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile

- name: Generate Chakra types
if: steps.cache-node-modules.outputs.cache-hit == 'true'
run: yarn chakra:typegen

- name: Install script dependencies
run: cd ./deploy/tools/affected-tests && yarn --frozen-lockfile

Expand Down Expand Up @@ -264,6 +284,10 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile

- name: Generate Chakra types
if: steps.cache-node-modules.outputs.cache-hit == 'true'
run: yarn chakra:typegen

- name: Download affected tests list
if: ${{ needs.pw_affected_tests.result == 'success' }}
uses: actions/download-artifact@v4
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy-review-l2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ on:
- neon_devnet
- optimism
- optimism_sepolia
- optimism_superchain
- polygon
- rootstock
- scroll_sepolia
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/deploy-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ on:
- neon_devnet
- optimism
- optimism_sepolia
- optimism_superchain
- polygon
- rari_testnet
- rootstock
- shibarium
- scroll_sepolia
- stability
- tac
- tac_turin
- zkevm
- zilliqa_prototestnet
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/upload-source-maps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile

- name: Generate Chakra types
if: steps.cache-node-modules.outputs.cache-hit == 'true'
run: yarn chakra:typegen

- name: Make production build with source maps
run: yarn build
env:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
/out/
/public/assets/envs.js
/public/assets/configs
/public/assets/multichain
/public/icons/sprite.svg
/public/icons/sprite.*.svg
/public/icons/registry.json
Expand Down
2 changes: 2 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -377,12 +377,14 @@
"optimism",
"optimism_interop_0",
"optimism_sepolia",
"optimism_superchain",
"polygon",
"rari_testnet",
"rootstock_testnet",
"scroll_sepolia",
"shibarium",
"stability_testnet",
"tac",
"tac_turin",
"zkevm",
"zilliqa_prototestnet",
Expand Down
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ WORKDIR /sitemap-generator
COPY ./deploy/tools/sitemap-generator/package.json ./deploy/tools/sitemap-generator/yarn.lock ./
RUN yarn --frozen-lockfile --network-timeout 100000

### MULTICHAIN CONFIG GENERATOR
# Install dependencies
WORKDIR /multichain-config-generator
COPY ./deploy/tools/multichain-config-generator/package.json ./deploy/tools/multichain-config-generator/yarn.lock ./
RUN yarn --frozen-lockfile --network-timeout 100000


# *****************************
# ****** STAGE 2: Build *******
Expand Down Expand Up @@ -106,6 +112,11 @@ COPY --from=deps /favicon-generator/node_modules ./deploy/tools/favicon-generato
# Copy dependencies and source code
COPY --from=deps /sitemap-generator/node_modules ./deploy/tools/sitemap-generator/node_modules

### MULTICHAIN CONFIG GENERATOR
# Copy dependencies and source code, then build
COPY --from=deps /multichain-config-generator/node_modules ./deploy/tools/multichain-config-generator/node_modules
RUN cd ./deploy/tools/multichain-config-generator && yarn build


# *****************************
# ******* STAGE 3: Run ********
Expand All @@ -130,8 +141,11 @@ RUN chown nextjs:nodejs .next
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json

# Copy tools
COPY --from=builder /app/deploy/tools/envs-validator/index.js ./envs-validator.js
COPY --from=builder /app/deploy/tools/feature-reporter/index.js ./feature-reporter.js
COPY --from=builder /app/deploy/tools/multichain-config-generator/dist ./deploy/tools/multichain-config-generator/dist

# Copy scripts
## Entripoint
Expand Down
23 changes: 22 additions & 1 deletion configs/app/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getEnvValue } from './utils';
export interface ApiPropsBase {
endpoint: string;
basePath?: string;
socketEndpoint?: string;
}

export interface ApiPropsFull extends ApiPropsBase {
Expand Down Expand Up @@ -100,6 +101,25 @@ const rewardsApi = (() => {
});
})();

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

try {
const url = new URL(apiHost);

return Object.freeze({
endpoint: apiHost,
socketEndpoint: `wss://${ url.host }`,
});
} catch (error) {
return;
}

})();

const statsApi = (() => {
const apiHost = getEnvValue('NEXT_PUBLIC_STATS_API_HOST');
if (!apiHost) {
Expand Down Expand Up @@ -135,7 +155,7 @@ const visualizeApi = (() => {
});
})();

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

Expand All @@ -145,6 +165,7 @@ const apis: Apis = Object.freeze({
bens: bensApi,
contractInfo: contractInfoApi,
metadata: metadataApi,
multichain: multichainApi,
rewards: rewardsApi,
stats: statsApi,
tac: tacApi,
Expand Down
27 changes: 27 additions & 0 deletions configs/app/features/address3rdPartyWidgets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Feature } from './types';

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

// config file will be downloaded at run-time and saved in the public folder
const widgets = parseEnvJson<Array<string>>(getEnvValue('NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS'));
const configUrl = getExternalAssetFilePath('NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL');

const title = 'Address 3rd party widgets';

const config: Feature<{ widgets: Array<string>; configUrl: string }> = (() => {
if (widgets && widgets.length > 0 && configUrl) {
return Object.freeze({
title,
isEnabled: true,
widgets,
configUrl,
});
}

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

export default config;
4 changes: 3 additions & 1 deletion configs/app/features/addressMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import type { Feature } from './types';

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

const title = 'Address metadata';

const config: Feature<{}> = (() => {
const config: Feature<{ isAddressTagsUpdateEnabled: boolean }> = (() => {
if (apis.metadata) {
return Object.freeze({
title,
isEnabled: true,
isAddressTagsUpdateEnabled: getEnvValue('NEXT_PUBLIC_METADATA_ADDRESS_TAGS_UPDATE_ENABLED') !== 'false',
});
}

Expand Down
15 changes: 11 additions & 4 deletions configs/app/features/blockchainInteraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,29 @@ import type { Feature } from './types';

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

const walletConnectProjectId = getEnvValue('NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID');

const title = 'Blockchain interaction (writing to contract, etc.)';

const config: Feature<{ walletConnect: { projectId: string } }> = (() => {

if (
// all chain parameters are required for wagmi provider
// @wagmi/chains/dist/index.d.ts
// all chain parameters are required for wagmi provider
// @wagmi/chains/dist/index.d.ts
const isSingleChain = Boolean(
chain.id &&
chain.name &&
chain.currency.name &&
chain.currency.symbol &&
chain.currency.decimals &&
chain.rpcUrls.length > 0 &&
chain.rpcUrls.length > 0,
);

const isOpSuperchain = opSuperchain.isEnabled;

if (
(isSingleChain || isOpSuperchain) &&
walletConnectProjectId
) {
return Object.freeze({
Expand Down
4 changes: 1 addition & 3 deletions configs/app/features/celo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import { getEnvValue } from '../utils';

const title = 'Celo chain';

const config: Feature<{ L2UpgradeBlock: number | undefined; BLOCKS_PER_EPOCH: number }> = (() => {
const config: Feature<{ }> = (() => {

if (getEnvValue('NEXT_PUBLIC_CELO_ENABLED') === 'true') {
return Object.freeze({
title,
isEnabled: true,
L2UpgradeBlock: getEnvValue('NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK') ? Number(getEnvValue('NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK')) : undefined,
BLOCKS_PER_EPOCH: 17_280,
});
}

Expand Down
2 changes: 2 additions & 0 deletions configs/app/features/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { default as advancedFilter } from './advancedFilter';
export { default as account } from './account';
export { default as addressVerification } from './addressVerification';
export { default as addressMetadata } from './addressMetadata';
export { default as address3rdPartyWidgets } from './address3rdPartyWidgets';
export { default as adsBanner } from './adsBanner';
export { default as adsText } from './adsText';
export { default as beaconChain } from './beaconChain';
Expand All @@ -26,6 +27,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 opSuperchain } from './opSuperchain';
export { default as pools } from './pools';
export { default as publicTagsSubmission } from './publicTagsSubmission';
export { default as restApiDocs } from './restApiDocs';
Expand Down
24 changes: 24 additions & 0 deletions configs/app/features/opSuperchain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Feature } from './types';

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

const isEnabled = getEnvValue('NEXT_PUBLIC_OP_SUPERCHAIN_ENABLED') === 'true';

const title = 'OP Superchain interop explorer';

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

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

export default config;
2 changes: 1 addition & 1 deletion configs/envs/.env.celo_alfajores
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=celo-alfajores.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CELO_ENABLED=true
NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK=26369280
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_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/celo.json
Expand All @@ -24,6 +23,7 @@ NEXT_PUBLIC_GAS_TRACKER_ENABLED=false
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0x9767ce30754afad2a3279b9df2d13257f467c3dad4e0e601271e66d16dfd1641
NEXT_PUBLIC_HAS_USER_OPS=true
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_STATS=['total_blocks','average_block_time','total_txs','wallet_addresses','current_epoch']
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['rgba(252, 255, 82, 1)'],'text_color':['rgba(0, 0, 0, 1)']}
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_MARKETPLACE_ENABLED=false
Expand Down
4 changes: 3 additions & 1 deletion configs/envs/.env.eth
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,6 @@ NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES=[{'name':'OpenSea','collection_url':'https://opensea.io/assets/ethereum/{hash}','instance_url':'https://opensea.io/assets/ethereum/{hash}/{id}','logo_url':'https://opensea.io/static/images/logos/opensea-logo.svg'},{'name':'Rarible','collection_url':'https://rarible.com/collection/{hash}/items','instance_url':'https://rarible.com/token/{hash}:{id}','logo_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/nft-marketplace-logos/rarible.png'},{'name':'Blur','collection_url':'https://blur.io/eth/collection/{hash}','instance_url':'https://blur.io/eth/asset/{hash}/{id}','logo_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/nft-marketplace-logos/blur.png'},{'name':'MagicEden','collection_url':'https://magiceden.io/collections/ethereum/{hash}','instance_url':'https://magiceden.io/item-details/ethereum/{hash}/{id}','logo_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/nft-marketplace-logos/magiceden.png'}]
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_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=address
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS=['talentprotocol', 'efp', 'webacy', 'deepdao', 'humanpassport', 'trustblock', 'bankless']
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/widgets/config.json
2 changes: 2 additions & 0 deletions configs/envs/.env.eth_sepolia
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws

NEXT_PUBLIC_HAS_CONTRACT_AUDIT_REPORTS=true

# Instance ENVs
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_DESKTOP={ "id": "632019", "width": "728", "height": "90" }
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE={ "id": "632018", "width": "320", "height": "100" }
Expand Down
Loading
Loading