Fixes for Release v2.7.0 (#3310)

* fix: correct optional chaining in label-issues-in-release workflow

- Updated the filter condition to ensure proper handling of optional chaining for issue labels when label doesn't have a description

* add reown to ignored origins of errors in rollbar monitoring

* export HintProps

* add recipe for Code component and adjust select component props

* fix screenshots

* fix validator schema for multichain explorer

* fix mobile lists in safari

* screenshot update

* deprecate NEXT_PUBLIC_ROLLUP_L1_BASE_URL env

* add support of new Tac operation type

* remove recaptcha token from query params

* add skin for multichain

* update multichain config

* fix: og meta tags were not rendered on the server

* enable NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE var for multichain

* disable e2e test job
This commit is contained in:
tom goriunov
2026-03-02 13:52:09 +01:00
committed by GitHub
parent dd80db3ac2
commit e6b7dbe3e0
120 changed files with 218 additions and 202 deletions
@@ -223,7 +223,7 @@ jobs:
const issues = associatedPullRequests
.nodes
.filter(({ closingIssuesReferences: { nodes: issues } }) => !issues?.some(({ labels }) => labels?.nodes?.some(({ description }) => description.toLowerCase().startsWith('release'))))
.filter(({ closingIssuesReferences: { nodes: issues } }) => !issues?.some(({ labels }) => labels?.nodes?.some(({ description }) => description?.toLowerCase().startsWith('release'))))
.map(({ closingIssuesReferences: { nodes: issues } }) => issues.map(({ number }) => number))
.flat();
+13 -11
View File
@@ -15,18 +15,20 @@ jobs:
contents: read
pull-requests: write
# publish_image:
# image will be published in e2e-tests.yml workflow
# name: Publish Docker image
# uses: './.github/workflows/publish-image.yml'
# secrets: inherit
e2e_tests:
name: Run e2e tests
needs: checks
uses: "./.github/workflows/e2e-tests.yml"
publish_image:
name: Publish Docker image
uses: './.github/workflows/publish-image.yml'
secrets: inherit
permissions: write-all
with:
platforms: linux/amd64
# e2e_tests:
# decided to disable e2e temporarily
# name: Run e2e tests
# needs: checks
# uses: "./.github/workflows/e2e-tests.yml"
# secrets: inherit
# permissions: write-all
version:
name: Pre-release version info
+2 -4
View File
@@ -15,15 +15,13 @@ const L2WithdrawalUrl = getEnvValue('NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL');
const parentChain: ParentChain | undefined = (() => {
const envValue = parseEnvJson<ParentChain>(getEnvValue('NEXT_PUBLIC_ROLLUP_PARENT_CHAIN'));
const baseUrl = stripTrailingSlash(getEnvValue('NEXT_PUBLIC_ROLLUP_L1_BASE_URL') || '');
if (!baseUrl && !envValue?.baseUrl) {
if (!envValue?.baseUrl) {
return;
}
return {
...envValue,
baseUrl: baseUrl || envValue?.baseUrl || '',
baseUrl: stripTrailingSlash(envValue.baseUrl),
};
})();
-1
View File
@@ -55,7 +55,6 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://arbitrum-one.publicnode.com
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/arbitrum-one.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com','currency':{'name':'Ether','symbol':'ETH','decimals':18},'isTestnet':false,'id':1,'name':'Ethereum Mainnet','rpcUrls':['https://eth.drpc.org']}
NEXT_PUBLIC_ROLLUP_STAGE_INDEX=1
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
+1 -1
View File
@@ -31,8 +31,8 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://arbitrum.llamarpc.com
NEXT_PUBLIC_NETWORK_SHORT_NAME=Arbitrum Nova
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/arbitrum-nova.png
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
-1
View File
@@ -44,7 +44,6 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/arbitrum-sepolia.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-sepolia.blockscout.com','currency':{'name':'Ether','symbol':'ETH','decimals':18},'isTestnet':true,'id':11155111,'name':'Sepolia','rpcUrls':['https://eth-sepolia.public.blastapi.io']}
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+1 -1
View File
@@ -67,7 +67,7 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/base-mainnet.png
NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://base.drpc.org?ref=559183','text':'Public RPC'}]
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://bridge.base.org/withdraw
NEXT_PUBLIC_ROLLUP_STAGE_INDEX=1
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
+1 -1
View File
@@ -55,7 +55,7 @@ NEXT_PUBLIC_NETWORK_SHORT_NAME=Mainnet
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/celo.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://mondo.celo.org/bridge
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+1 -1
View File
@@ -46,7 +46,7 @@ NEXT_PUBLIC_OG_DESCRIPTION=Redstone is the home for onchain games, worlds, and o
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/garnet.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-holesky.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-holesky.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://garnet.qry.live/withdraw
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+1 -1
View File
@@ -49,7 +49,7 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://alpha.megaeth.com/rpc
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/mega-eth.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://www.megaeth.com/
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+10
View File
@@ -8,6 +8,16 @@ NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/multichain-light.svg
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/multichain-dark.svg
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/multichain-light.svg
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/multichain-dark.svg
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/multichain.png
FAVICON_MASTER_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/favicons/multichain.png
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['linear-gradient(89deg,rgba(83,83,211) 50.49%,rgba(155,155,255) 99.38%)'],'text_color':['rgba(225,225,255,1)'],'button':{'_default':{'background':['rgba(16,17,18,1)']},'_hover':{'background':['rgba(74,71,127,1)']}}}
NEXT_PUBLIC_COLOR_THEME_OVERRIDES={'bg':{'primary':{'_light':{'value':'rgba(255,255,255,1)'},'_dark':{'value':'rgba(35,43,55,1)'}}},'text':{'primary':{'_light':{'value':'rgba(16,17,18,0.8)'},'_dark':{'value':'rgba(255,255,255,0.8)'}},'secondary':{'_light':{'value':'rgba(113,128,150,1)'},'_dark':{'value':'rgba(160,174,192,1)'}}},'hover':{'_light':{'value':'rgba(155,155,255,1)'},'_dark':{'value':'rgba(155,155,255,1)'}},'selected':{'control':{'text':{'_light':{'value':'rgba(16,17,18,1)'},'_dark':{'value':'rgba(247,250,252,1)'}},'bg':{'_light':{'value':'rgba(16,17,18,0.04)'},'_dark':{'value':'rgba(247,250,252,0.06)'}}},'option':{'bg':{'_light':{'value':'rgba(83,83,211,1)'},'_dark':{'value':'rgba(114,114,233,1)'}}}},'icon':{'primary':{'_light':{'value':'rgba(113,128,150,1)'},'_dark':{'value':'rgba(160,174,192,1)'}},'secondary':{'_light':{'value':'rgba(160,174,192,1)'},'_dark':{'value':'rgba(113,128,150,1)'}}},'button':{'primary':{'_light':{'value':'rgba(83,83,211,1)'},'_dark':{'value':'rgba(114,114,233,1)'},'text':{'_light':{'value':'rgba(255,255,255,0.92)'},'_dark':{'value':'rgba(255,255,255,0.92)'}}}},'link':{'primary':{'_light':{'value':'rgba(83,83,211,1)'},'_dark':{'value':'rgba(114,114,233,1)'}}},'graph':{'line':{'_light':{'value':'rgba(94,87,112,1)'},'_dark':{'value':'rgba(194,190,208,1)'}},'gradient':{'start':{'_light':{'value':'rgba(94,87,112,0.3)'},'_dark':{'value':'rgba(194,190,208,0.3)'}},'stop':{'_light':{'value':'rgba(94,87,112,0)'},'_dark':{'value':'rgba(194,190,208,0)'}}}},'stats':{'bg':{'_light':{'value':'rgba(16,17,18,0.04)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}},'topbar':{'bg':{'_light':{'value':'rgba(16,17,18,0.04)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}},'navigation':{'text':{'selected':{'_light':{'value':'rgba(16,17,18,1)'},'_dark':{'value':'rgba(247,250,252,1)'}}},'bg':{'selected':{'_light':{'value':'rgba(16,17,18,0.04)'},'_dark':{'value':'rgba(255,255,255,0.06)'}}}},'tabs':{'text':{'primary':{'_light':{'value':'rgba(113,128,150,1)'},'_dark':{'value':'rgba(160,174,192,1)'}}}}}
NEXT_PUBLIC_MULTICHAIN_ENABLED=true
NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST=https://multichain-aggregator.services.blockscout.com
NEXT_PUBLIC_MULTICHAIN_CLUSTER=multichain
+1 -1
View File
@@ -63,7 +63,7 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/optimism-mainnet.png
NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://optimism.drpc.org?ref=559183','text':'Public RPC'}]
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://app.optimism.io/bridge/withdraw
NEXT_PUBLIC_ROLLUP_STAGE_INDEX=1
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
+1 -1
View File
@@ -50,7 +50,7 @@ NEXT_PUBLIC_NETWORK_NAME=OP Sepolia
NEXT_PUBLIC_NETWORK_RPC_URL=https://sepolia.optimism.io
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-sepolia.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://app.optimism.io/bridge/withdraw
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+1 -1
View File
@@ -30,7 +30,7 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=false
NEXT_PUBLIC_OTHER_LINKS=[]
NEXT_PUBLIC_ROLLUP_DA_CELESTIA_CELENIUM_URL=https://mocha-4.celenium.io/blob
NEXT_PUBLIC_ROLLUP_DA_CELESTIA_NAMESPACE=0x00000000000000000000000000000000000000ca1de12a9905be97beaf
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://arbitrum-sepolia.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://arbitrum-sepolia.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_SEO_ENHANCED_DATA_ENABLED=false
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE=jazzicon
+1 -1
View File
@@ -39,7 +39,7 @@ NEXT_PUBLIC_NETWORK_RPC_URL=https://sepolia-rpc.scroll.io
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/scroll-testnet.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-sepolia.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=scroll
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://scroll-sepolia.blockscout.com
+1 -1
View File
@@ -56,7 +56,7 @@ NEXT_PUBLIC_NETWORK_SHORT_NAME=Puppynet
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/shibarium-mainnet.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=shibarium
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://www.shibariumscan.io
+2 -1
View File
@@ -40,7 +40,8 @@ NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-c
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://spb.explorer.tac.build
NEXT_PUBLIC_TAC_OPERATION_LIFECYCLE_API_HOST=https://tac-spb-operation-lifecycle.k8s.blockscout.com
# NEXT_PUBLIC_TAC_OPERATION_LIFECYCLE_API_HOST=https://tac-spb-operation-lifecycle.k8s.blockscout.com
NEXT_PUBLIC_TAC_OPERATION_LIFECYCLE_API_HOST=https://tac-spb-operation-lifecycle.k8s-dev.blockscout.com
NEXT_PUBLIC_TAC_TON_EXPLORER_URL=https://testnet.tonviewer.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
+1 -1
View File
@@ -39,7 +39,7 @@ NEXT_PUBLIC_NETWORK_NAME=Polygon CDK Stavanger
NEXT_PUBLIC_NETWORK_RPC_URL=https://sn2-stavanger-rpc.eu-north-2.gateway.fm
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth-sepolia.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=zkEvm
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
NEXT_PUBLIC_STATS_API_HOST=https://polygon-cdk-stavanger.blockscout.com
+1 -1
View File
@@ -51,7 +51,7 @@ NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/zksync.png
NEXT_PUBLIC_OTHER_LINKS=[{'url':'https://zksync.drpc.org?ref=559183','text':'Public RPC'}]
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_TYPE=zkSync
NEXT_PUBLIC_SAFE_TX_SERVICE_URL=https://safe-transaction-zksync.safe.global
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+1 -1
View File
@@ -54,7 +54,7 @@ NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE=validation
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/zora-mainnet.png
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth.blockscout.com/
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://eth.blockscout.com'}
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://bridge.zora.energy
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
+1 -6
View File
@@ -152,12 +152,7 @@ function getEnvsPlaceholders(filePath: string): Promise<Array<string>> {
}
function printDeprecationWarning(envsMap: Record<string, string>) {
if (
envsMap.NEXT_PUBLIC_ROLLUP_L1_BASE_URL
) {
// eslint-disable-next-line max-len
console.warn('❗ The NEXT_PUBLIC_ROLLUP_L1_BASE_URL variables are now deprecated and will be removed in the next release. Please migrate to the NEXT_PUBLIC_ROLLUP_PARENT_CHAIN variable.');
}
}
function checkDeprecatedEnvs(envsMap: Record<string, string>) {
+1 -14
View File
@@ -13,7 +13,6 @@ import type { AddressProfileAPIConfig } from 'types/client/addressProfileAPIConf
import type { GasRefuelProviderConfig } from 'types/client/gasRefuelProviderConfig';
import { GAS_UNITS } from 'types/client/gasTracker';
import type { GasUnit } from 'types/client/gasTracker';
import type { MultichainProviderConfig } from 'types/client/multichainProviderConfig';
import { PROVIDERS as TX_INTERPRETATION_PROVIDERS } from 'types/client/txInterpretation';
import { VALIDATORS_CHAIN_TYPE } from 'types/client/validators';
import type { ValidatorsChainType } from 'types/client/validators';
@@ -30,14 +29,6 @@ import * as uiSchemas from './schemas/ui';
import * as featuresSchemas from './schemas/features';
import servicesSchema from './schemas/services';
const multichainProviderConfigSchema: yup.ObjectSchema<MultichainProviderConfig> = yup.object({
name: yup.string().required(),
url_template: yup.string().required(),
logo: yup.string().required(),
dapp_id: yup.string(),
promo: yup.boolean(),
});
const schema = yup
.object()
.noUnknown(true, (params) => {
@@ -79,11 +70,6 @@ const schema = yup
NEXT_PUBLIC_SAFE_TX_SERVICE_URL: yup.string().test(urlTest),
NEXT_PUBLIC_IS_SUAVE_CHAIN: yup.boolean(),
NEXT_PUBLIC_METASUITES_ENABLED: yup.boolean(),
NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG: yup
.array()
.transform(replaceQuotes)
.json()
.of(multichainProviderConfigSchema),
NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG: yup
.mixed()
.test('shape', 'Invalid schema were provided for NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG, it should have name and url template', (data) => {
@@ -170,6 +156,7 @@ const schema = yup
.concat(featuresSchemas.highlightsConfigSchema)
.concat(featuresSchemas.marketplaceSchema)
.concat(featuresSchemas.megaEthSchema)
.concat(featuresSchemas.multichainButtonSchema)
.concat(featuresSchemas.nameServicesSchema)
.concat(featuresSchemas.rollupSchema)
.concat(featuresSchemas.tacSchema)
@@ -12,6 +12,7 @@ import * as uiSchemas from './schemas/ui';
import * as featuresSchemas from './schemas/features';
import servicesSchemas from './schemas/services';
import { replaceQuotes } from 'configs/app/utils';
import { IDENTICON_TYPES } from 'types/views/address';
const schema = yup
.object()
@@ -38,6 +39,10 @@ const schema = yup
NEXT_PUBLIC_NETWORK_SHORT_NAME: yup.string(),
NEXT_PUBLIC_IS_TESTNET: yup.boolean(),
// 3. UI views configuration
// Some settings that we actually support in multichain mode
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE: yup.string().oneOf(IDENTICON_TYPES),
// 5. Features configuration
// NOTE!: Not all features are supported in multichain mode, and some of them not relevant or enabled per chain basis
// Below listed supported features and the features that are enabled by default, so we have to turn them off
@@ -63,8 +68,9 @@ const schema = yup
.concat(uiSchemas.footerSchema)
.concat(uiSchemas.miscSchema)
.concat(featuresSchemas.adsSchema)
.concat(featuresSchemas.userOpsSchema)
.concat(featuresSchemas.defiDropdownSchema)
.concat(featuresSchemas.multichainButtonSchema)
.concat(featuresSchemas.userOpsSchema)
.concat(servicesSchemas);
export default schema;
@@ -9,6 +9,7 @@ export * from './defiDropdown';
export * from './highlights';
export * from './marketplace';
export * from './megaEth';
export * from './multichainButton';
export * from './nameServices';
export * from './rollup';
export * from './tac';
@@ -0,0 +1,21 @@
import { replaceQuotes } from 'configs/app/utils';
import { MultichainProviderConfig } from 'types/client/multichainProviderConfig';
import * as yup from 'yup';
const multichainProviderConfigSchema: yup.ObjectSchema<MultichainProviderConfig> = yup.object({
name: yup.string().required(),
url_template: yup.string().required(),
logo: yup.string().required(),
dapp_id: yup.string(),
promo: yup.boolean(),
});
export const multichainButtonSchema = yup
.object()
.shape({
NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG: yup
.array()
.transform(replaceQuotes)
.json()
.of(multichainProviderConfigSchema)
});
@@ -12,46 +12,46 @@ const parentChainCurrencySchema = yup
decimals: yup.number().required(),
});
const parentChainSchema = yup
.object()
.transform(replaceQuotes)
.json()
.shape({
id: yup.number(),
name: yup.string(),
baseUrl: yup.string().test(urlTest).required(),
rpcUrls: yup.array().of(yup.string().test(urlTest)),
currency: yup
.mixed()
.test(
'shape',
(ctx) => {
try {
parentChainCurrencySchema.validateSync(ctx.originalValue);
throw new Error('Unknown validation error');
} catch (error: unknown) {
const message = getYupValidationErrorMessage(error);
return 'in \"currency\" property ' + (message ? `${ message }` : '');
}
},
(data) => {
const isUndefined = data === undefined;
return isUndefined || parentChainCurrencySchema.isValidSync(data);
},
),
isTestnet: yup.boolean(),
});
export const rollupSchema = yup
.object()
.shape({
NEXT_PUBLIC_ROLLUP_TYPE: yup.string().oneOf(ROLLUP_TYPES),
NEXT_PUBLIC_ROLLUP_L1_BASE_URL: yup
.string()
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN: yup
.object()
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
is: (value: string) => value,
then: (schema) => schema.test(urlTest).required(),
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined'),
then: (schema) => {
return schema.transform(replaceQuotes).json().shape({
id: yup.number(),
name: yup.string(),
baseUrl: yup.string().test(urlTest).required(),
rpcUrls: yup.array().of(yup.string().test(urlTest)),
currency: yup
.mixed()
.test(
'shape',
(ctx) => {
try {
parentChainCurrencySchema.validateSync(ctx.originalValue);
throw new Error('Unknown validation error');
} catch (error: unknown) {
const message = getYupValidationErrorMessage(error);
return 'in \"currency\" property ' + (message ? `${ message }` : '');
}
},
(data) => {
const isUndefined = data === undefined;
return isUndefined || parentChainCurrencySchema.isValidSync(data);
},
),
isTestnet: yup.boolean(),
})
},
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined',
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL: yup
.string()
@@ -113,34 +113,6 @@ export const rollupSchema = yup
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN: yup
.mixed()
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
is: (value: string) => value,
then: (schema) => {
return schema.test(
'shape',
(ctx) => {
try {
parentChainSchema.validateSync(ctx.originalValue);
throw new Error('Unknown validation error');
} catch (error: unknown) {
const message = getYupValidationErrorMessage(error);
return 'Invalid schema were provided for NEXT_PUBLIC_ROLLUP_PARENT_CHAIN' + (message ? `: ${ message }` : '');
}
},
(data) => {
const isUndefined = data === undefined;
return isUndefined || parentChainSchema.isValidSync(data);
}
)
},
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined',
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_DA_CELESTIA_NAMESPACE: yup
.string()
.min(60)
@@ -1,5 +1,4 @@
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://example.com
NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS=true
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://explorer.duckchain.io','currency':{'name':'Quack','symbol':'QUACK','decimals':18},'isTestnet':true,'id':42,'name':'DuckChain','rpcUrls':['https://rpc.duckchain.io']}
@@ -11,6 +11,7 @@ NEXT_PUBLIC_API_DOCS_TABS=[]
NEXT_PUBLIC_FEATURED_NETWORKS=http://example.com
NEXT_PUBLIC_FOOTER_LINKS=http://example.com
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_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'url_template': 'https://app.zerion.io/{address}/overview', 'logo': 'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-logos/zerion.svg'}]
NEXT_PUBLIC_NETWORK_ICON=http://example.com
NEXT_PUBLIC_NETWORK_ICON_DARK=http://example.com
NEXT_PUBLIC_NETWORK_LOGO=http://example.com
@@ -1,5 +1,4 @@
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://example.com
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://example.com
NEXT_PUBLIC_FAULT_PROOF_ENABLED=true
NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS=true
+1
View File
@@ -31,3 +31,4 @@
| NEXT_PUBLIC_VIEWS_CONTRACT_LANGUAGE_FILTERS | `Array<'solidity' \| 'vyper' \| 'yul' \| 'scilla' \| 'geas' \| 'stylus_rust'>` | Pass an array of contract languages that will be displayed as options in the filter on the verified contract page. | - | `['solidity','vyper','yul','geas','stylus_rust']` | `['solidity','vyper','yul','scilla']` | v1.37.0+ | v2.6.0+ | Replaced with configuration retrieved from the API. |
| NEXT_PUBLIC_SAVE_ON_GAS_ENABLED | `boolean` | Set to "true" to enable the feature | - | - | `true` | v1.35.0+ | v2.7.0+ | Feature is deprecated. |
| NEXT_PUBLIC_API_SPEC_URL | `string` | Spec of Blockscout core API to be displayed on the page. | - | `https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml` | `https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml` | v1.0.x+ | v2.7.0+ | The URL is now constructed automatically based on the configuration received from the API. |
| NEXT_PUBLIC_ROLLUP_L1_BASE_URL | `string` | Blockscout base URL for parent network. | Required | - | `'http://eth-goerli.blockscout.com'` | v1.24.0+ | v2.7.0+ | Replaced with NEXT_PUBLIC_ROLLUP_PARENT_CHAIN |
+2 -3
View File
@@ -530,7 +530,7 @@ Ads are enabled by default on all self-hosted instances. If you would like to di
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_ROLLUP_TYPE | `'optimistic' \| 'arbitrum' \| 'shibarium' \| 'zkEvm' \| 'zkSync' \| 'scroll'` | Rollup chain type | Required | - | `'optimistic'` | v1.24.0+ |
| NEXT_PUBLIC_ROLLUP_L1_BASE_URL | `string` | Blockscout base URL for parent network. **DEPRECATED** _Use `NEXT_PUBLIC_ROLLUP_PARENT_CHAIN` instead_ | Required | - | `'http://eth-goerli.blockscout.com'` | v1.24.0+ |
| NEXT_PUBLIC_ROLLUP_PARENT_CHAIN | `ParentChain`, see details [below](#parent-chain-configuration-properties) | Configuration parameters for the parent chain. | Required | - | `{'baseUrl':'https://explorer.duckchain.io'}` | v1.38.0+ |
| NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL | `string` | URL for rollup to parent chain withdrawals (Optimistic stack only) | - | - | `https://app.optimism.io/bridge/withdraw` | v1.24.0+ |
| NEXT_PUBLIC_ROLLUP_LAYER_NUMBER | `number` | Layer number of the rollup | - | `2` | `3` | v2.7.0+ |
| NEXT_PUBLIC_ROLLUP_STAGE_INDEX | `1 \| 2` | Reflects the maturity and decentralization level of the chain based on [L2BEAT's framework](https://medium.com/l2beat/introducing-stages-a-framework-to-evaluate-rollups-maturity-d290bb22befe). The label will be added to the sidebar according to the provided stage index. Not applicable for testnets. | - | - | `1` | v2.1.0+ |
@@ -539,7 +539,6 @@ Ads are enabled by default on all self-hosted instances. If you would like to di
| NEXT_PUBLIC_INTEROP_ENABLED | `boolean` | Enables "Interop messages" page (Optimistic stack only) | - | `false` | `true` | v1.39.0+ |
| NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS | `boolean` | Set to `true` to display "Latest blocks" widget instead of "Latest batches" on the home page | - | - | `true` | v1.36.0+ |
| NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED | `boolean` | Enables "Output roots" page (Optimistic stack only) | - | `false` | `true` | v1.37.0+ |
| NEXT_PUBLIC_ROLLUP_PARENT_CHAIN | `ParentChain`, see details [below](#parent-chain-configuration-properties) | Configuration parameters for the parent chain. | - | - | `{'baseUrl':'https://explorer.duckchain.io'}` | v1.38.0+ |
| NEXT_PUBLIC_ROLLUP_DA_CELESTIA_NAMESPACE | `string` | Hex-string for creating a link to the transaction batch on the [Celenium explorer](https://celenium.io). "0x"-format and 60 symbol length. Available only for Arbitrum roll-ups. | - | - | `0x00000000000000000000000000000000000000ca1de12a9905be97beaf` | v1.38.0+ |
| NEXT_PUBLIC_ROLLUP_DA_CELESTIA_CELENIUM_URL | `string` | URL for the Selenium explorer. It is used to create links to the Data Availability Blobs page. The URL should contain the full path without any search parameters related to the blob, as these will be constructed at runtime for each blob separately. Available only for Optimistic or Arbitrum roll-ups. | - | - | `https://mocha.celenium.io/blob` | v2.0.2+ |
@@ -547,9 +546,9 @@ Ads are enabled by default on all self-hosted instances. If you would like to di
| Variable | Type| Description | Compulsoriness | Default value | Example value |
| --- | --- | --- | --- | --- | --- |
| baseUrl | `string` | Base url of the chain explorer. | Required | - | `https://explorer.duckchain.io` |
| id | `number` | Chain id, see [https://chainlist.org](https://chainlist.org) for the reference. | - | - | `42` |
| name | `string` | Displayed name of the chain. Set to customize parent chain transaction status labels in the UI (e.g., "Sent to <chain-name>"). Currently, this setting is applicable only for Arbitrum-based chains. | - | - | `DuckChain` |
| baseUrl | `string` | Base url of the chain explorer. | Required | - | `https://explorer.duckchain.io` |
| rpcUrls | `Array<string>` | Chain public RPC server urls, see [https://chainlist.org](https://chainlist.org) for the reference. | - | - | `['https://rpc.duckchain.io']` |
| currency | `{ name: string; symbol: string; decimals: number; }` | Chain currency config. | - | - | `{ name: Quack, symbol: QUA, decimals: 18 }` |
| isTestnet | `boolean` | Set to true if network is testnet. | - | - | `true` |
+2
View File
@@ -14,6 +14,8 @@ export function getTacOperationStatus(type: tac.OperationType) {
return 'Error';
case tac.OperationType.ROLLBACK:
return 'Rollback';
case tac.OperationType.INSUFFICIENT_FEE:
return 'Insufficient fee';
case tac.OperationType.PENDING:
return 'Pending';
default:
+1
View File
@@ -55,6 +55,7 @@ export const clientConfig: Configuration | undefined = feature.isEnabled ? {
const originFileName = getExceptionOriginFileName(item);
const IGNORED_ORIGIN_FILE_NAMES_CHUNKS = [
'/node_modules/@walletconnect',
'/node_modules/@reown',
];
if (originFileName && IGNORED_ORIGIN_FILE_NAMES_CHUNKS.some((chunk) => originFileName.includes(chunk))) {
+1 -7
View File
@@ -2,7 +2,6 @@ import React from 'react';
import type { Route } from 'nextjs-routes';
import type { Props as PageProps } from 'nextjs/getServerSideProps/handlers';
import PageMetadata from 'nextjs/PageMetadata';
import useAdblockDetect from 'lib/hooks/useAdblockDetect';
import useGetCsrfToken from 'lib/hooks/useGetCsrfToken';
@@ -27,12 +26,7 @@ const PageNextJs = <Pathname extends Route['pathname']>(props: Props<Pathname>)
const isMixPanelInitialized = mixpanel.useInit();
mixpanel.useLogPageView(isMixPanelInitialized);
return (
<>
<PageMetadata pathname={ props.pathname } query={ props.query } apiData={ props.apiData }/>
{ isMounted ? props.children : null }
</>
);
return isMounted ? props.children : null;
};
export default React.memo(PageNextJs);
+1 -1
View File
@@ -48,7 +48,7 @@
"@blockscout/multichain-aggregator-types": "2.1.2",
"@blockscout/points-types": "1.4.0-alpha.1",
"@blockscout/stats-types": "2.11.1",
"@blockscout/tac-operation-lifecycle-types": "0.0.1-alpha.6",
"@blockscout/tac-operation-lifecycle-types": "1.1.0",
"@blockscout/visualizer-types": "0.2.0",
"@blockscout/zetachain-cctx-types": "^1.0.0-rc.6",
"@chakra-ui/react": "3.33.0",
+35 -29
View File
@@ -8,6 +8,9 @@ import React from 'react';
import type { NextPageWithLayout } from 'nextjs/types';
import type { Route } from 'nextjs-routes';
import PageMetadata from 'nextjs/PageMetadata';
import config from 'configs/app';
import getSocketUrl from 'lib/api/getSocketUrl';
import useQueryClientConfig from 'lib/api/useQueryClientConfig';
@@ -57,7 +60,7 @@ If you don't understand what this console is for, close it now and stay safe.`;
const CONSOLE_SCAM_WARNING_DELAY_MS = 500;
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
function MyApp({ Component, pageProps, router }: AppPropsWithLayout) {
const growthBook = initGrowthBook(pageProps.uuid);
useLoadFeatures(growthBook);
@@ -96,34 +99,37 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const socketUrl = !config.features.multichain.isEnabled ? getSocketUrl() : undefined;
return (
<ChakraProvider>
<RollbarProvider config={ rollbarConfig }>
<AppErrorBoundary
{ ...ERROR_SCREEN_STYLES }
Container={ AppErrorGlobalContainer }
>
<QueryClientProvider client={ queryClient }>
<Web3Provider>
<AppContextProvider pageProps={ pageProps }>
<GrowthBookProvider growthbook={ growthBook }>
<SocketProvider url={ socketUrl }>
<RewardsProvider>
<MarketplaceContextProvider>
<SettingsContextProvider>
{ content }
</SettingsContextProvider>
</MarketplaceContextProvider>
</RewardsProvider>
</SocketProvider>
</GrowthBookProvider>
<ReactQueryDevtools buttonPosition="bottom-left" position="left"/>
<GoogleAnalytics/>
</AppContextProvider>
</Web3Provider>
</QueryClientProvider>
</AppErrorBoundary>
</RollbarProvider>
</ChakraProvider>
<>
<PageMetadata pathname={ router.pathname as Route['pathname'] } query={ pageProps.query } apiData={ pageProps.apiData }/>
<ChakraProvider>
<RollbarProvider config={ rollbarConfig }>
<AppErrorBoundary
{ ...ERROR_SCREEN_STYLES }
Container={ AppErrorGlobalContainer }
>
<QueryClientProvider client={ queryClient }>
<Web3Provider>
<AppContextProvider pageProps={ pageProps }>
<GrowthBookProvider growthbook={ growthBook }>
<SocketProvider url={ socketUrl }>
<RewardsProvider>
<MarketplaceContextProvider>
<SettingsContextProvider>
{ content }
</SettingsContextProvider>
</MarketplaceContextProvider>
</RewardsProvider>
</SocketProvider>
</GrowthBookProvider>
<ReactQueryDevtools buttonPosition="bottom-left" position="left"/>
<GoogleAnalytics/>
</AppContextProvider>
</Web3Provider>
</QueryClientProvider>
</AppErrorBoundary>
</RollbarProvider>
</ChakraProvider>
</>
);
}
+5 -5
View File
@@ -31,20 +31,20 @@ export const ENVS_MAP: Record<string, Array<[string, string]>> = {
],
shibariumRollup: [
[ 'NEXT_PUBLIC_ROLLUP_TYPE', 'shibarium' ],
[ 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', 'https://localhost:3101' ],
[ 'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN', '{"baseUrl":"https://localhost:3101"}' ],
],
zkEvmRollup: [
[ 'NEXT_PUBLIC_ROLLUP_TYPE', 'zkEvm' ],
[ 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', 'https://localhost:3101' ],
[ 'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN', '{"baseUrl":"https://localhost:3101"}' ],
],
zkSyncRollup: [
[ 'NEXT_PUBLIC_ROLLUP_TYPE', 'zkSync' ],
[ 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', 'https://localhost:3101' ],
[ 'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN', '{"baseUrl":"https://localhost:3101"}' ],
[ 'NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS', 'none' ],
],
scrollRollup: [
[ 'NEXT_PUBLIC_ROLLUP_TYPE', 'scroll' ],
[ 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', 'https://localhost:3101' ],
[ 'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN', '{"baseUrl":"https://localhost:3101"}' ],
],
bridgedTokens: [
[ 'NEXT_PUBLIC_BRIDGED_TOKENS_CHAINS', '[{"id":"1","title":"Ethereum","short_title":"ETH","base_url":"https://eth.blockscout.com/token/"},{"id":"56","title":"Binance Smart Chain","short_title":"BSC","base_url":"https://bscscan.com/token/"},{"id":"99","title":"POA","short_title":"POA","base_url":"https://blockscout.com/poa/core/token/"}]' ],
@@ -103,7 +103,7 @@ export const ENVS_MAP: Record<string, Array<[string, string]>> = {
],
interop: [
[ 'NEXT_PUBLIC_ROLLUP_TYPE', 'optimistic' ],
[ 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', 'https://localhost:3101' ],
[ 'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN', '{"baseUrl":"https://localhost:3101"}' ],
[ 'NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL', 'https://localhost:3102' ],
[ 'NEXT_PUBLIC_INTEROP_ENABLED', 'true' ],
],
+6 -5
View File
@@ -16,7 +16,7 @@ export type ViewMode = 'default' | 'compact';
export interface SelectOption<Value extends string = string> {
label: string;
renderLabel?: () => React.ReactNode;
renderLabel?: (place: 'item' | 'value-text') => React.ReactNode;
value: Value;
icon?: React.ReactNode;
afterElement?: React.ReactNode;
@@ -166,7 +166,7 @@ export const SelectValueText = React.forwardRef<
WebkitBoxOrient: 'vertical',
display: '-webkit-box',
}}>
{ item.renderLabel ? item.renderLabel() : context.collection.stringifyItem(item) }
{ item.renderLabel ? item.renderLabel('value-text') : context.collection.stringifyItem(item) }
</span>
) }
</Flex>
@@ -272,7 +272,7 @@ export const Select = React.forwardRef<HTMLDivElement, SelectProps>((props, ref)
.map((item: SelectOption) => (
<React.Fragment key={ item.value }>
<SelectItem item={ item }>
{ item.renderLabel ? item.renderLabel() : item.label }
{ item.renderLabel ? item.renderLabel('item') : item.label }
</SelectItem>
{ item.afterElement }
</React.Fragment>
@@ -292,7 +292,7 @@ export interface SelectAsyncProps extends Omit<SelectProps, 'collection'> {
}
export const SelectAsync = React.forwardRef<HTMLDivElement, SelectAsyncProps>((props, ref) => {
const { placeholder, portalled = true, loading, loadOptions, extraControls, onValueChange, errorText, mode, ...rest } = props;
const { placeholder, portalled = true, loading, loadOptions, extraControls, onValueChange, errorText, mode, contentHeader, ...rest } = props;
const [ collection, setCollection ] = React.useState<ListCollection<SelectOption>>(createListCollection<SelectOption>({ items: [] }));
const [ inputValue, setInputValue ] = React.useState('');
@@ -340,9 +340,10 @@ export const SelectAsync = React.forwardRef<HTMLDivElement, SelectAsyncProps>((p
/>
{ extraControls }
</Box>
{ contentHeader }
{ collection.items.map((item) => (
<SelectItem item={ item } key={ item.value }>
{ item.renderLabel ? item.renderLabel() : item.label }
{ item.renderLabel ? item.renderLabel('item') : item.label }
</SelectItem>
)) }
</SelectContent>
+2 -2
View File
@@ -8,14 +8,14 @@ import { IconButton } from '../../chakra/icon-button';
import type { TooltipProps } from '../../chakra/tooltip';
import { Tooltip } from '../../chakra/tooltip';
interface Props extends IconButtonProps {
export interface HintProps extends IconButtonProps {
label: string | React.ReactNode;
tooltipProps?: Partial<TooltipProps>;
isLoading?: boolean;
as?: React.ElementType;
}
export const Hint = React.memo(({ label, tooltipProps, isLoading, boxSize = 5, ...rest }: Props) => {
export const Hint = React.memo(({ label, tooltipProps, isLoading, boxSize = 5, ...rest }: HintProps) => {
return (
<Tooltip
content={ label }
+20
View File
@@ -0,0 +1,20 @@
import { defineRecipe } from '@chakra-ui/react';
import { recipe as badgeRecipe } from './badge.recipe';
const { variants, defaultVariants } = badgeRecipe;
export const recipe = defineRecipe({
className: 'chakra-code',
base: {
fontFamily: 'mono',
alignItems: 'center',
display: 'inline-flex',
borderRadius: 'l2',
},
variants,
defaultVariants: {
...defaultVariants,
size: 'sm',
},
});
+2
View File
@@ -5,6 +5,7 @@ import { recipe as button } from './button.recipe';
import { recipe as checkbox } from './checkbox.recipe';
import { recipe as checkmark } from './checkmark.recipe';
import { recipe as closeButton } from './close-button.recipe';
import { recipe as code } from './code.recipe';
import { recipe as dialog } from './dialog.recipe';
import { recipe as drawer } from './drawer.recipe';
import { recipe as emptyState } from './empty-state.recipe';
@@ -36,6 +37,7 @@ import { recipe as tooltip } from './tooltip.recipe';
export const recipes = {
badge,
button,
code,
checkmark,
closeButton,
input,
+1
View File
@@ -68,6 +68,7 @@ const IGNORED_ENVS = [
'NEXT_PUBLIC_VIEWS_CONTRACT_LANGUAGE_FILTERS',
'NEXT_PUBLIC_API_SPEC_URL',
'NEXT_PUBLIC_ROLLUP_L1_BASE_URL',
];
function parseScriptArgs() {
+1 -4
View File
@@ -25,10 +25,7 @@ const ExportCSV = ({ filters }: Props) => {
const [ isLoading, setIsLoading ] = React.useState(false);
const apiFetchFactory = React.useCallback(async(recaptchaToken?: string) => {
const url = buildUrl('general:advanced_filter_csv', undefined, {
...filters,
recaptcha_response: recaptchaToken,
}, undefined, multichainContext?.chain);
const url = buildUrl('general:advanced_filter_csv', undefined, filters, undefined, multichainContext?.chain);
const response = await fetch(url, {
headers: {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 146 KiB

@@ -48,7 +48,7 @@ const TokenTransfersCrossChainListItem = ({ data, isLoading, rowGap = 3, current
<Time timestamp={ timestamp } format="lll_s"/>
</Skeleton>
) }
<Grid templateColumns="100px 1fr" columnGap={ 2 } rowGap={ rowGap }>
<Grid templateColumns="100px minmax(0, 1fr)" columnGap={ 2 } rowGap={ rowGap }>
<Skeleton loading={ isLoading }>
Source token
</Skeleton>
@@ -66,7 +66,7 @@ const TransactionsCrossChainListItem = ({ data, isLoading, rowGap = 3, currentAd
<Time timestamp={ timestamp } format="lll_s"/>
</Skeleton>
) }
<Grid templateColumns="120px 1fr" columnGap={ 2 } rowGap={ rowGap }>
<Grid templateColumns="120px minmax(0, 1fr)" columnGap={ 2 } rowGap={ rowGap }>
<Skeleton loading={ isLoading }>
Source tx
</Skeleton>
-1
View File
@@ -51,7 +51,6 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
to_period: exportType !== 'holders' ? dayjs(data.to).toISOString() : null,
filter_type: filterType,
filter_value: filterValue,
recaptcha_response: recaptchaToken,
}, undefined, multichainContext?.chain);
const response = await fetch(url, {
+1 -1
View File
@@ -98,7 +98,7 @@ const ChainWidget = ({ data, isLoading, metrics }: Props) => {
borderColor={{ _light: 'blackAlpha.200', _dark: 'whiteAlpha.200' }}
_hover={ !isLoading ? {
bgColor: { _light: 'gray.50', _dark: 'whiteAlpha.100' },
borderColor: { _light: 'blue.100', _dark: 'blue.700' },
borderColor: 'hover',
} : undefined }
p={ 6 }
flexBasis="calc((100% - 3 * 12px) / 4)"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

@@ -28,26 +28,28 @@ const TacOperationLifecycleAccordionItemContent = ({ isLast, data }: Props) => {
</ItemRow>
) }
<ItemRow label="Transactions">
<Box
display="flex"
flexDirection="column"
rowGap={ 3 }
py="6px"
width="100%"
overflow="hidden"
>
{
data.transactions.map((tx) => {
if (tx.type === tac.BlockchainType.TON) {
return <TxEntityTon key={ tx.hash } hash={ tx.hash }/>;
}
{ data.transactions.length > 0 && (
<ItemRow label="Transactions">
<Box
display="flex"
flexDirection="column"
rowGap={ 3 }
py="6px"
width="100%"
overflow="hidden"
>
{
data.transactions.map((tx) => {
if (tx.type === tac.BlockchainType.TON) {
return <TxEntityTon key={ tx.hash } hash={ tx.hash }/>;
}
return <TxEntity key={ tx.hash } hash={ tx.hash } icon={{ name: 'brands/tac' }}/>;
})
}
</Box>
</ItemRow>
return <TxEntity key={ tx.hash } hash={ tx.hash } icon={{ name: 'brands/tac' }}/>;
})
}
</Box>
</ItemRow>
) }
{ data.note && (
<ItemRow label="Note">
@@ -22,6 +22,7 @@ const TacOperationStatus = ({ status, isLoading, noTooltip }: Props) => {
switch (status) {
case tac.OperationType.ERROR:
case tac.OperationType.INSUFFICIENT_FEE:
return <StatusTag type="error" text={ text } loading={ isLoading }/>;
case tac.OperationType.ROLLBACK:
return (
Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Some files were not shown because too many files have changed in this diff Show More