mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
@@ -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: yarn lint:eslint
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -25,6 +25,7 @@ on:
|
||||
- neon_devnet
|
||||
- optimism
|
||||
- optimism_sepolia
|
||||
- optimism_superchain
|
||||
- polygon
|
||||
- rootstock
|
||||
- scroll_sepolia
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Vendored
+2
@@ -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",
|
||||
|
||||
+14
@@ -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 *******
|
||||
@@ -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 ********
|
||||
@@ -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
|
||||
|
||||
+22
-1
@@ -7,6 +7,7 @@ import { getEnvValue } from './utils';
|
||||
export interface ApiPropsBase {
|
||||
endpoint: string;
|
||||
basePath?: string;
|
||||
socketEndpoint?: string;
|
||||
}
|
||||
|
||||
export interface ApiPropsFull extends ApiPropsBase {
|
||||
@@ -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) {
|
||||
@@ -135,7 +155,7 @@ const visualizeApi = (() => {
|
||||
});
|
||||
})();
|
||||
|
||||
type Apis = {
|
||||
export type Apis = {
|
||||
general: ApiPropsFull;
|
||||
} & Partial<Record<Exclude<ApiName, 'general'>, ApiPropsBase>>;
|
||||
|
||||
@@ -145,6 +165,7 @@ const apis: Apis = Object.freeze({
|
||||
bens: bensApi,
|
||||
contractInfo: contractInfoApi,
|
||||
metadata: metadataApi,
|
||||
multichain: multichainApi,
|
||||
rewards: rewardsApi,
|
||||
stats: statsApi,
|
||||
tac: tacApi,
|
||||
|
||||
@@ -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;
|
||||
@@ -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',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ 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');
|
||||
|
||||
@@ -9,15 +10,21 @@ 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({
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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';
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Set of ENVs for OP Mainnet network explorer
|
||||
# https://xxx.blockscout.com
|
||||
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=optimism_superchain"
|
||||
|
||||
# Local ENVs
|
||||
NEXT_PUBLIC_APP_PROTOCOL=http
|
||||
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_OP_SUPERCHAIN_ENABLED=true
|
||||
|
||||
# TODO @tom2drum remove this
|
||||
SKIP_ENVS_VALIDATION=true
|
||||
|
||||
NEXT_PUBLIC_API_SPEC_URL=none
|
||||
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-mainnet-light.svg
|
||||
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism-mainnet-dark.svg
|
||||
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/optimism.svg
|
||||
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/optimism.svg
|
||||
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
|
||||
NEXT_PUBLIC_IS_TESTNET=true
|
||||
NEXT_PUBLIC_USE_NEXT_JS_PROXY=false
|
||||
@@ -0,0 +1,45 @@
|
||||
# Set of ENVs for TAC network explorer
|
||||
# https://explorer.tac.build
|
||||
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=tac"
|
||||
|
||||
# Local ENVs
|
||||
NEXT_PUBLIC_APP_PROTOCOL=http
|
||||
NEXT_PUBLIC_APP_HOST=localhost
|
||||
NEXT_PUBLIC_APP_PORT=3000
|
||||
NEXT_PUBLIC_APP_ENV=development
|
||||
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
|
||||
|
||||
# Instance ENVs
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
|
||||
NEXT_PUBLIC_API_BASE_PATH=/
|
||||
NEXT_PUBLIC_API_HOST=explorer.tac.build
|
||||
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
|
||||
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/tac.json
|
||||
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
|
||||
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0x9e2386a15e263fffc7b481ae1a6b8d71aa94b87c7683b3f2d756bb912622d638
|
||||
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
|
||||
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['no-repeat center/100% auto url(https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-skins/tac.jpg)'],'text_color':['rgba(242,235,255,1)'],'button':{'_default':{'background':['rgba(30,23,44,1)']},'_hover':{'background':['rgba(66,14,70,1)']}}}
|
||||
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
|
||||
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
|
||||
NEXT_PUBLIC_NAME_SERVICE_API_HOST=https://bens.services.blockscout.com
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=TAC
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=TAC
|
||||
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/tac-light.svg
|
||||
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/tac-dark.svg
|
||||
NEXT_PUBLIC_NETWORK_ID=239
|
||||
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/tac-light.svg
|
||||
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/tac-dark.svg
|
||||
NEXT_PUBLIC_NETWORK_NAME=TAC
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL=https://rpc.ankr.com/tac
|
||||
NEXT_PUBLIC_NETWORK_SHORT_NAME=TAC
|
||||
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
|
||||
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/tac-turin.png
|
||||
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
|
||||
NEXT_PUBLIC_STATS_API_HOST=https://explorer.tac.build
|
||||
NEXT_PUBLIC_TAC_OPERATION_LIFECYCLE_API_HOST=https://tac-operation-lifecycle.k8s.blockscout.com
|
||||
NEXT_PUBLIC_TAC_TON_EXPLORER_URL=https://tonviewer.com
|
||||
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
|
||||
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
|
||||
@@ -0,0 +1,48 @@
|
||||
/* eslint-disable no-restricted-properties */
|
||||
import type { MultichainConfig } from 'types/multichain';
|
||||
|
||||
import config from 'configs/app';
|
||||
|
||||
function isRunningInDocker() {
|
||||
return process.env.HOSTNAME !== undefined;
|
||||
}
|
||||
|
||||
let value: MultichainConfig | undefined = undefined;
|
||||
|
||||
async function fetchConfig() {
|
||||
if (process.env.NEXT_RUNTIME !== 'edge') {
|
||||
throw new Error('NEXT_RUNTIME is not edge');
|
||||
}
|
||||
|
||||
// In edge runtime, we need to use absolute URLs
|
||||
// When in Docker, use the internal hostname
|
||||
const baseUrl = isRunningInDocker() ?
|
||||
`http://${ process.env.HOSTNAME }:${ config.app.port || 3000 }` :
|
||||
config.app.baseUrl;
|
||||
|
||||
const url = baseUrl + '/assets/multichain/config.json';
|
||||
const response = await fetch(url);
|
||||
const json = await response.json();
|
||||
|
||||
value = json as MultichainConfig;
|
||||
return value;
|
||||
}
|
||||
|
||||
export async function load() {
|
||||
if (!value) {
|
||||
return new Promise<MultichainConfig | undefined>((resolve, reject) => {
|
||||
fetchConfig()
|
||||
.then((value) => {
|
||||
resolve(value);
|
||||
}).catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve(value);
|
||||
}
|
||||
|
||||
export function getValue() {
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { MultichainConfig } from 'types/multichain';
|
||||
|
||||
let value: MultichainConfig | undefined = undefined;
|
||||
|
||||
function readFileConfig() {
|
||||
// eslint-disable-next-line no-restricted-properties
|
||||
if (process.env.NEXT_RUNTIME !== 'nodejs') {
|
||||
throw new Error('NEXT_RUNTIME is not nodejs');
|
||||
}
|
||||
|
||||
try {
|
||||
const path = require('path');
|
||||
const { readFileSync } = require('fs');
|
||||
const publicFolder = path.resolve('public');
|
||||
const configPath = path.resolve(publicFolder, 'assets/multichain/config.json');
|
||||
|
||||
const config = readFileSync(configPath, 'utf8');
|
||||
|
||||
value = JSON.parse(config) as MultichainConfig;
|
||||
return value;
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export async function load() {
|
||||
if (!value) {
|
||||
return new Promise<MultichainConfig | undefined>((resolve) => {
|
||||
const value = readFileConfig();
|
||||
resolve(value);
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve(value);
|
||||
}
|
||||
|
||||
export function getValue() {
|
||||
if (!value) {
|
||||
return readFileConfig();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { MultichainConfig } from 'types/multichain';
|
||||
|
||||
import config from 'configs/app';
|
||||
import * as multichainConfigNodejs from 'configs/multichain/config.nodejs';
|
||||
import { isBrowser } from 'toolkit/utils/isBrowser';
|
||||
|
||||
const multichainConfig: () => MultichainConfig | undefined = () => {
|
||||
if (!config.features.opSuperchain.isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBrowser()) {
|
||||
return window.__multichainConfig;
|
||||
}
|
||||
|
||||
return multichainConfigNodejs.getValue();
|
||||
};
|
||||
|
||||
export default multichainConfig;
|
||||
@@ -26,6 +26,7 @@ ASSETS_ENVS=(
|
||||
"NEXT_PUBLIC_NETWORK_ICON"
|
||||
"NEXT_PUBLIC_NETWORK_ICON_DARK"
|
||||
"NEXT_PUBLIC_OG_IMAGE_URL"
|
||||
"NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL"
|
||||
)
|
||||
|
||||
# Create the assets directory if it doesn't exist
|
||||
|
||||
@@ -64,6 +64,9 @@ node --no-warnings ./og_image_generator.js
|
||||
# Create envs.js file with run-time environment variables for the client app
|
||||
./make_envs_script.sh
|
||||
|
||||
# Generate multichain config
|
||||
node ./deploy/tools/multichain-config-generator/dist/index.js
|
||||
|
||||
# Generate sitemap.xml and robots.txt files
|
||||
./sitemap_generator.sh
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ async function validateEnvs(appEnvs: Record<string, string>) {
|
||||
'NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL',
|
||||
'NEXT_PUBLIC_MARKETPLACE_GRAPH_LINKS_URL',
|
||||
'NEXT_PUBLIC_FOOTER_LINKS',
|
||||
'NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL',
|
||||
];
|
||||
|
||||
for await (const envName of envsWithJsonConfig) {
|
||||
|
||||
@@ -35,8 +35,8 @@ import type { ChainIndicatorId, HeroBannerButtonState, HeroBannerConfig, HomeSta
|
||||
import { type NetworkVerificationTypeEnvs, type NetworkExplorer, type FeaturedNetwork, NETWORK_GROUPS } from '../../../types/networks';
|
||||
import { COLOR_THEME_IDS } from '../../../types/settings';
|
||||
import type { FontFamily } from '../../../types/ui';
|
||||
import type { AddressFormat, AddressViewId } from '../../../types/views/address';
|
||||
import { ADDRESS_FORMATS, ADDRESS_VIEWS_IDS, IDENTICON_TYPES } from '../../../types/views/address';
|
||||
import type { AddressFormat, AddressViewId, Address3rdPartyWidget } from '../../../types/views/address';
|
||||
import { ADDRESS_FORMATS, ADDRESS_VIEWS_IDS, IDENTICON_TYPES, ADDRESS_3RD_PARTY_WIDGET_PAGES } from '../../../types/views/address';
|
||||
import { BLOCK_FIELDS_IDS } from '../../../types/views/block';
|
||||
import type { BlockFieldId } from '../../../types/views/block';
|
||||
import type { NftMarketplaceItem } from '../../../types/views/nft';
|
||||
@@ -71,12 +71,12 @@ const urlTest: yup.TestConfig = {
|
||||
exclusive: true,
|
||||
};
|
||||
|
||||
const getYupValidationErrorMessage = (error: unknown) =>
|
||||
typeof error === 'object' &&
|
||||
error !== null &&
|
||||
'errors' in error &&
|
||||
Array.isArray(error.errors) ?
|
||||
error.errors.join(', ') :
|
||||
const getYupValidationErrorMessage = (error: unknown) =>
|
||||
typeof error === 'object' &&
|
||||
error !== null &&
|
||||
'errors' in error &&
|
||||
Array.isArray(error.errors) ?
|
||||
error.errors.join(', ') :
|
||||
'';
|
||||
|
||||
const marketplaceAppSchema: yup.ObjectSchema<MarketplaceAppOverview> = yup
|
||||
@@ -448,16 +448,6 @@ const celoSchema = yup
|
||||
.object()
|
||||
.shape({
|
||||
NEXT_PUBLIC_CELO_ENABLED: yup.boolean(),
|
||||
NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK: yup
|
||||
.string()
|
||||
.when('NEXT_PUBLIC_CELO_ENABLED', {
|
||||
is: (value: boolean) => value,
|
||||
then: (schema) => schema.min(0).optional(),
|
||||
otherwise: (schema) => schema.max(
|
||||
-1,
|
||||
'NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK cannot not be used if NEXT_PUBLIC_CELO_ENABLED is not set to "true"',
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
const adButlerConfigSchema = yup
|
||||
@@ -590,6 +580,7 @@ const footerLinkSchema: yup.ObjectSchema<CustomLink> = yup
|
||||
.object({
|
||||
text: yup.string().required(),
|
||||
url: yup.string().test(urlTest).required(),
|
||||
iconUrl: yup.array().of(yup.string().required().test(urlTest)),
|
||||
});
|
||||
|
||||
const footerLinkGroupSchema: yup.ObjectSchema<CustomLinksGroup> = yup
|
||||
@@ -666,6 +657,25 @@ const bridgedTokensSchema = yup
|
||||
}),
|
||||
});
|
||||
|
||||
const addressMetadataSchema = yup
|
||||
.object()
|
||||
.shape({
|
||||
NEXT_PUBLIC_METADATA_SERVICE_API_HOST: yup
|
||||
.string()
|
||||
.test(urlTest),
|
||||
NEXT_PUBLIC_METADATA_ADDRESS_TAGS_UPDATE_ENABLED: yup
|
||||
.boolean()
|
||||
.when('NEXT_PUBLIC_METADATA_SERVICE_API_HOST', {
|
||||
is: (value: string) => Boolean(value),
|
||||
then: (schema) => schema,
|
||||
otherwise: (schema) => schema.test(
|
||||
'not-exist',
|
||||
'NEXT_PUBLIC_METADATA_ADDRESS_TAGS_UPDATE_ENABLED cannot not be used if NEXT_PUBLIC_METADATA_SERVICE_API_HOST is not defined',
|
||||
value => value === undefined,
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
const deFiDropdownItemSchema: yup.ObjectSchema<DeFiDropdownItem> = yup
|
||||
.object({
|
||||
text: yup.string().required(),
|
||||
@@ -690,6 +700,46 @@ const externalTxsConfigSchema: yup.ObjectSchema<TxExternalTxsConfig> = yup.objec
|
||||
explorer_url_template: yup.string().required(),
|
||||
});
|
||||
|
||||
const address3rdPartyWidgetsConfigSchema = yup
|
||||
.object()
|
||||
.shape({
|
||||
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL: yup
|
||||
.mixed()
|
||||
.test('shape', 'Invalid schema were provided for NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL, it should have name, url, icon, title, value', (data) => {
|
||||
const isUndefined = data === undefined;
|
||||
const parsedData = typeof data === 'string' ? JSON.parse(data) : data;
|
||||
const valueSchema = yup.lazy((objValue) => {
|
||||
let schema = yup.object();
|
||||
Object.keys(objValue).forEach((key) => {
|
||||
schema = schema.shape({
|
||||
[key]: yup.object<Address3rdPartyWidget>().shape({
|
||||
name: yup.string().required(),
|
||||
url: yup.string().required(),
|
||||
icon: yup.string().required(),
|
||||
title: yup.string().required(),
|
||||
hint: yup.string().optional(),
|
||||
valuePath: yup.string().required(),
|
||||
pages: yup.array().of(yup.string().oneOf(ADDRESS_3RD_PARTY_WIDGET_PAGES)).required(),
|
||||
chainIds: yup.object<Record<string, string>>().optional(),
|
||||
}),
|
||||
});
|
||||
});
|
||||
return schema;
|
||||
});
|
||||
return isUndefined || valueSchema.isValidSync(parsedData);
|
||||
}),
|
||||
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS: yup
|
||||
.array()
|
||||
.transform(replaceQuotes)
|
||||
.json()
|
||||
.of(yup.string())
|
||||
.when('NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL', {
|
||||
is: (value: string) => value,
|
||||
then: (schema) => schema,
|
||||
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS cannot not be used if NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL is not provided'),
|
||||
}),
|
||||
});
|
||||
|
||||
const schema = yup
|
||||
.object()
|
||||
.noUnknown(true, (params) => {
|
||||
@@ -952,7 +1002,6 @@ const schema = yup
|
||||
NEXT_PUBLIC_VISUALIZE_API_BASE_PATH: yup.string(),
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: yup.string().test(urlTest),
|
||||
NEXT_PUBLIC_NAME_SERVICE_API_HOST: yup.string().test(urlTest),
|
||||
NEXT_PUBLIC_METADATA_SERVICE_API_HOST: yup.string().test(urlTest),
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: yup.string().test(urlTest),
|
||||
NEXT_PUBLIC_GRAPHIQL_TRANSACTION: yup
|
||||
.mixed()
|
||||
@@ -1107,6 +1156,8 @@ const schema = yup
|
||||
.concat(beaconChainSchema)
|
||||
.concat(bridgedTokensSchema)
|
||||
.concat(sentrySchema)
|
||||
.concat(tacSchema);
|
||||
.concat(tacSchema)
|
||||
.concat(address3rdPartyWidgetsConfigSchema)
|
||||
.concat(addressMetadataSchema);
|
||||
|
||||
export default schema;
|
||||
|
||||
@@ -7,3 +7,5 @@ NEXT_PUBLIC_VIEWS_ADDRESS_BECH_32_PREFIX=foo
|
||||
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY=xxx
|
||||
NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY=deprecated
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL=['https://example.com','https://example2.com']
|
||||
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://example.com
|
||||
NEXT_PUBLIC_METADATA_ADDRESS_TAGS_UPDATE_ENABLED=false
|
||||
@@ -89,3 +89,5 @@ NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG=[{'name': 'zerion', 'url_template
|
||||
NEXT_PUBLIC_GAS_REFUEL_PROVIDER_CONFIG={'name': 'Need gas?', 'dapp_id': 'smol-refuel', 'url_template': 'https://smolrefuel.com/?outboundChain={chainId}&partner=blockscout&utm_source=blockscout&utm_medium=address&disableBridges=true', 'logo': 'https://blockscout-content.s3.amazonaws.com/smolrefuel-logo-action-button.png'}
|
||||
NEXT_PUBLIC_SAVE_ON_GAS_ENABLED=true
|
||||
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=https://example.com
|
||||
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS=['widget-1', 'widget-2']
|
||||
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://example.com
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
NEXT_PUBLIC_CELO_ENABLED=true
|
||||
NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK=420
|
||||
NEXT_PUBLIC_CELO_ENABLED=true
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"widget-1": {
|
||||
"name": "Widget 1",
|
||||
"url": "https://example.com/widget-1/{address}",
|
||||
"icon": "https://example.com/icon.svg",
|
||||
"title": "Widget 1",
|
||||
"hint": "Widget 1 hint",
|
||||
"valuePath": "result.value",
|
||||
"pages": [ "eoa", "contract", "token" ]
|
||||
},
|
||||
"widget-2": {
|
||||
"name": "Widget 2",
|
||||
"url": "https://example.com/widget-2/{address}",
|
||||
"icon": "https://example.com/icon.svg",
|
||||
"title": "Widget 2",
|
||||
"valuePath": "value",
|
||||
"pages": [ "eoa" ]
|
||||
},
|
||||
"widget-3": {
|
||||
"name": "Widget 3",
|
||||
"url": "https://example.com/widget-3/{address}?chainId={chainId}",
|
||||
"icon": "https://example.com/icon.svg",
|
||||
"title": "Widget 3",
|
||||
"valuePath": "result.length",
|
||||
"pages": [ "token" ],
|
||||
"chainIds": {
|
||||
"1": "eth",
|
||||
"10": "op"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,11 @@
|
||||
"links": [
|
||||
{
|
||||
"text": "Develop",
|
||||
"url": "https://example.com"
|
||||
"url": "https://example.com",
|
||||
"iconUrl": [
|
||||
"https://example.com/mocks/image_s.jpg",
|
||||
"https://example.com/mocks/image_svg.svg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "Grants",
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.DS_Store
|
||||
@@ -0,0 +1,80 @@
|
||||
import { mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { dirname, resolve as resolvePath } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { Worker } from 'node:worker_threads';
|
||||
|
||||
const currentFilePath = fileURLToPath(import.meta.url);
|
||||
const currentDir = dirname(currentFilePath);
|
||||
|
||||
const EXPLORER_URLS = [
|
||||
'https://optimism-interop-alpha-0.blockscout.com',
|
||||
'https://optimism-interop-alpha-1.blockscout.com',
|
||||
];
|
||||
|
||||
function getSlug(url: string) {
|
||||
return new URL(url).hostname.replace('.blockscout.com', '').replace('.k8s-dev', '');
|
||||
}
|
||||
|
||||
async function computeChainConfig(url: string): Promise<unknown> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const workerPath = resolvePath(currentDir, 'worker.js');
|
||||
|
||||
const worker = new Worker(workerPath, {
|
||||
workerData: { url },
|
||||
env: {} // Start with empty environment
|
||||
});
|
||||
|
||||
worker.on('message', (config) => {
|
||||
resolve(config);
|
||||
});
|
||||
|
||||
worker.on('error', (error) => {
|
||||
console.error('Worker error:', error);
|
||||
reject(error);
|
||||
});
|
||||
|
||||
worker.on('exit', (code) => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Worker stopped with exit code ${ code }`));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
if (!process.env.NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST) {
|
||||
console.log('ℹ️ NEXT_PUBLIC_MULTICHAIN_AGGREGATOR_API_HOST is not set, skipping multichain config generation\n');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('🌀 Generating multichain config...');
|
||||
const configs = await Promise.all(EXPLORER_URLS.map(computeChainConfig));
|
||||
|
||||
const config = {
|
||||
chains: configs.map((config, index) => {
|
||||
return {
|
||||
slug: getSlug(EXPLORER_URLS[index]),
|
||||
config,
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
const outputDir = resolvePath(currentDir, '../../../../public/assets/multichain');
|
||||
mkdirSync(outputDir, { recursive: true });
|
||||
|
||||
const outputPathJson = resolvePath(outputDir, 'config.json');
|
||||
writeFileSync(outputPathJson, JSON.stringify(config, null, 2));
|
||||
|
||||
const outputPathJs = resolvePath(outputDir, 'config.js');
|
||||
writeFileSync(outputPathJs, `window.__multichainConfig = ${ JSON.stringify(config) };`);
|
||||
|
||||
console.log('👍 Done!\n');
|
||||
} catch (error) {
|
||||
console.error('🚨 Error generating multichain config:', error);
|
||||
console.log('\n');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "@blockscout/multichain-config-generator",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build --logLevel error",
|
||||
"generate": "node dist/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "5.4.2",
|
||||
"vite": "6.3.5",
|
||||
"vite-plugin-dts": "4.5.4",
|
||||
"@types/node": "22.12.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"outDir": "./dist",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"configs/*": ["../../../configs/*"],
|
||||
"lib/*": ["../../../lib/*"],
|
||||
"toolkit/*": ["../../../toolkit/*"],
|
||||
"types/*": ["../../../types/*"]
|
||||
},
|
||||
"types": ["node"],
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"index.ts",
|
||||
"worker.ts",
|
||||
"../app/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { resolve } from 'path';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
lib: {
|
||||
entry: {
|
||||
index: resolve(__dirname, 'index.ts'),
|
||||
worker: resolve(__dirname, 'worker.ts'),
|
||||
},
|
||||
formats: [ 'es' ],
|
||||
fileName: (format, entryName) => `${ entryName }.js`,
|
||||
},
|
||||
rollupOptions: {
|
||||
external: [ 'node:worker_threads', 'node:url', 'node:path', 'node:fs' ],
|
||||
output: {
|
||||
dir: 'dist',
|
||||
entryFileNames: '[name].js',
|
||||
chunkFileNames: '[name].js',
|
||||
assetFileNames: '[name].[ext]',
|
||||
},
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
configs: resolve(__dirname, '../../../configs'),
|
||||
lib: resolve(__dirname, '../../../lib'),
|
||||
toolkit: resolve(__dirname, '../../../toolkit'),
|
||||
types: resolve(__dirname, '../../../types'),
|
||||
},
|
||||
preserveSymlinks: true,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
/* eslint-disable no-console */
|
||||
import { parentPort, workerData } from 'node:worker_threads';
|
||||
|
||||
interface WorkerData {
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface ChainConfig {
|
||||
envs: Record<string, string>;
|
||||
}
|
||||
|
||||
async function fetchChainConfig(url: string): Promise<ChainConfig> {
|
||||
const response = await fetch(`${ url }/node-api/config`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch config from ${ url }: ${ response.statusText }`);
|
||||
}
|
||||
const config = await response.json();
|
||||
return config as ChainConfig;
|
||||
}
|
||||
|
||||
async function computeConfig() {
|
||||
try {
|
||||
const { url } = workerData as WorkerData;
|
||||
console.log(' ⏳ Fetching chain config from:', url);
|
||||
|
||||
// 1. Fetch chain config
|
||||
const chainConfig = await fetchChainConfig(url);
|
||||
|
||||
// 2. Set environment variables
|
||||
Object.entries(chainConfig.envs).forEach(([ key, value ]) => {
|
||||
// eslint-disable-next-line no-restricted-properties
|
||||
process.env[key] = value;
|
||||
});
|
||||
|
||||
// 3. Import and compute app config
|
||||
const { 'default': appConfig } = await import('configs/app/index');
|
||||
|
||||
console.log(' ✅ Config computed for:', url);
|
||||
|
||||
// 4. Send config back to main thread
|
||||
parentPort?.postMessage(appConfig);
|
||||
} catch (error) {
|
||||
console.error(' ❌ Worker error:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
computeConfig();
|
||||
@@ -0,0 +1,978 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/helper-string-parser@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687"
|
||||
integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8"
|
||||
integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==
|
||||
|
||||
"@babel/parser@^7.27.2":
|
||||
version "7.27.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.5.tgz#ed22f871f110aa285a6fd934a0efed621d118826"
|
||||
integrity sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.27.3"
|
||||
|
||||
"@babel/types@^7.27.3":
|
||||
version "7.27.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.3.tgz#c0257bedf33aad6aad1f406d35c44758321eb3ec"
|
||||
integrity sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==
|
||||
dependencies:
|
||||
"@babel/helper-string-parser" "^7.27.1"
|
||||
"@babel/helper-validator-identifier" "^7.27.1"
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18"
|
||||
integrity sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz#bc766407f1718923f6b8079c8c61bf86ac3a6a4f"
|
||||
integrity sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.5.tgz#4290d6d3407bae3883ad2cded1081a234473ce26"
|
||||
integrity sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.5.tgz#40c11d9cbca4f2406548c8a9895d321bc3b35eff"
|
||||
integrity sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz#49d8bf8b1df95f759ac81eb1d0736018006d7e34"
|
||||
integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz#e27a5d92a14886ef1d492fd50fc61a2d4d87e418"
|
||||
integrity sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz#97cede59d638840ca104e605cdb9f1b118ba0b1c"
|
||||
integrity sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz#71c77812042a1a8190c3d581e140d15b876b9c6f"
|
||||
integrity sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz#f7b7c8f97eff8ffd2e47f6c67eb5c9765f2181b8"
|
||||
integrity sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz#2a0be71b6cd8201fa559aea45598dffabc05d911"
|
||||
integrity sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz#763414463cd9ea6fa1f96555d2762f9f84c61783"
|
||||
integrity sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz#428cf2213ff786a502a52c96cf29d1fcf1eb8506"
|
||||
integrity sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz#5cbcc7fd841b4cd53358afd33527cd394e325d96"
|
||||
integrity sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz#0d954ab39ce4f5e50f00c4f8c4fd38f976c13ad9"
|
||||
integrity sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz#0e7dd30730505abd8088321e8497e94b547bfb1e"
|
||||
integrity sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz#5669af81327a398a336d7e40e320b5bbd6e6e72d"
|
||||
integrity sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz#b2357dd153aa49038967ddc1ffd90c68a9d2a0d4"
|
||||
integrity sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz#53b4dfb8fe1cee93777c9e366893bd3daa6ba63d"
|
||||
integrity sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz#a0206f6314ce7dc8713b7732703d0f58de1d1e79"
|
||||
integrity sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz#2a796c87c44e8de78001d808c77d948a21ec22fd"
|
||||
integrity sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz#28d0cd8909b7fa3953af998f2b2ed34f576728f0"
|
||||
integrity sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz#a28164f5b997e8247d407e36c90d3fd5ddbe0dc5"
|
||||
integrity sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz#6eadbead38e8bd12f633a5190e45eff80e24007e"
|
||||
integrity sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz#bab6288005482f9ed2adb9ded7e88eba9a62cc0d"
|
||||
integrity sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==
|
||||
|
||||
"@esbuild/[email protected]":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz#7fc114af5f6563f19f73324b5d5ff36ece0803d1"
|
||||
integrity sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==
|
||||
|
||||
"@jridgewell/sourcemap-codec@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||
|
||||
"@microsoft/[email protected]":
|
||||
version "7.30.6"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.30.6.tgz#cd9c434521dda3b226cc0f6aefb9c20afaf99c92"
|
||||
integrity sha512-znmFn69wf/AIrwHya3fxX6uB5etSIn6vg4Q4RB/tb5VDDs1rqREc+AvMC/p19MUN13CZ7+V/8pkYPTj7q8tftg==
|
||||
dependencies:
|
||||
"@microsoft/tsdoc" "~0.15.1"
|
||||
"@microsoft/tsdoc-config" "~0.17.1"
|
||||
"@rushstack/node-core-library" "5.13.1"
|
||||
|
||||
"@microsoft/api-extractor@^7.50.1":
|
||||
version "7.52.8"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.52.8.tgz#7cc944f44ca1b1ad9d7272ab5d98e81987c1f8ca"
|
||||
integrity sha512-cszYIcjiNscDoMB1CIKZ3My61+JOhpERGlGr54i6bocvGLrcL/wo9o+RNXMBrb7XgLtKaizZWUpqRduQuHQLdg==
|
||||
dependencies:
|
||||
"@microsoft/api-extractor-model" "7.30.6"
|
||||
"@microsoft/tsdoc" "~0.15.1"
|
||||
"@microsoft/tsdoc-config" "~0.17.1"
|
||||
"@rushstack/node-core-library" "5.13.1"
|
||||
"@rushstack/rig-package" "0.5.3"
|
||||
"@rushstack/terminal" "0.15.3"
|
||||
"@rushstack/ts-command-line" "5.0.1"
|
||||
lodash "~4.17.15"
|
||||
minimatch "~3.0.3"
|
||||
resolve "~1.22.1"
|
||||
semver "~7.5.4"
|
||||
source-map "~0.6.1"
|
||||
typescript "5.8.2"
|
||||
|
||||
"@microsoft/tsdoc-config@~0.17.1":
|
||||
version "0.17.1"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz#e0f0b50628f4ad7fe121ca616beacfe6a25b9335"
|
||||
integrity sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==
|
||||
dependencies:
|
||||
"@microsoft/tsdoc" "0.15.1"
|
||||
ajv "~8.12.0"
|
||||
jju "~1.4.0"
|
||||
resolve "~1.22.2"
|
||||
|
||||
"@microsoft/[email protected]", "@microsoft/tsdoc@~0.15.1":
|
||||
version "0.15.1"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz#d4f6937353bc4568292654efb0a0e0532adbcba2"
|
||||
integrity sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==
|
||||
|
||||
"@rollup/pluginutils@^5.1.4":
|
||||
version "5.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.4.tgz#bb94f1f9eaaac944da237767cdfee6c5b2262d4a"
|
||||
integrity sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==
|
||||
dependencies:
|
||||
"@types/estree" "^1.0.0"
|
||||
estree-walker "^2.0.2"
|
||||
picomatch "^4.0.2"
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz#f39f09f60d4a562de727c960d7b202a2cf797424"
|
||||
integrity sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz#d19af7e23760717f1d879d4ca3d2cd247742dff2"
|
||||
integrity sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz#1c3a2fbf205d80641728e05f4a56c909e95218b7"
|
||||
integrity sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz#aa66d2ba1a25e609500e13bef06dc0e71cc0c0d4"
|
||||
integrity sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz#df10a7b6316a0ef1028c6ca71a081124c537e30d"
|
||||
integrity sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz#a3fdce8a05e95b068cbcb46e4df5185e407d0c35"
|
||||
integrity sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz#49f766c55383bd0498014a9d76924348c2f3890c"
|
||||
integrity sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz#1d4d7d32fc557e17d52e1857817381ea365e2959"
|
||||
integrity sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz#f4fc317268441e9589edad3be8f62b6c03009bc1"
|
||||
integrity sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz#63a1f1b0671cb17822dabae827fef0e443aebeb7"
|
||||
integrity sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz#c659b01cc6c0730b547571fc3973e1e955369f98"
|
||||
integrity sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz#612e746f9ad7e58480f964d65e0d6c3f4aae69a8"
|
||||
integrity sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz#4610dbd1dcfbbae32fbc10c20ae7387acb31110c"
|
||||
integrity sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz#054911fab40dc83fafc21e470193c058108f19d8"
|
||||
integrity sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz#98896eca8012547c7f04bd07eaa6896825f9e1a5"
|
||||
integrity sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz#01cf56844a1e636ee80dfb364e72c2b7142ad896"
|
||||
integrity sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz#e67c7531df6dff0b4c241101d4096617fbca87c3"
|
||||
integrity sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz#7eeada98444e580674de6989284e4baacd48ea65"
|
||||
integrity sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz#516c4b54f80587b4a390aaf4940b40870271d35d"
|
||||
integrity sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==
|
||||
|
||||
"@rollup/[email protected]":
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz#848f99b0d9936d92221bb6070baeff4db6947a30"
|
||||
integrity sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==
|
||||
|
||||
"@rushstack/[email protected]":
|
||||
version "5.13.1"
|
||||
resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz#e56b915ecb08b5a92711acac6b233417353a32dc"
|
||||
integrity sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==
|
||||
dependencies:
|
||||
ajv "~8.13.0"
|
||||
ajv-draft-04 "~1.0.0"
|
||||
ajv-formats "~3.0.1"
|
||||
fs-extra "~11.3.0"
|
||||
import-lazy "~4.0.0"
|
||||
jju "~1.4.0"
|
||||
resolve "~1.22.1"
|
||||
semver "~7.5.4"
|
||||
|
||||
"@rushstack/[email protected]":
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@rushstack/rig-package/-/rig-package-0.5.3.tgz#ea4d8a3458540b1295500149c04e645f23134e5d"
|
||||
integrity sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==
|
||||
dependencies:
|
||||
resolve "~1.22.1"
|
||||
strip-json-comments "~3.1.1"
|
||||
|
||||
"@rushstack/[email protected]":
|
||||
version "0.15.3"
|
||||
resolved "https://registry.yarnpkg.com/@rushstack/terminal/-/terminal-0.15.3.tgz#365e0ae5ac73bb4883b096ae36c5011f52911861"
|
||||
integrity sha512-DGJ0B2Vm69468kZCJkPj3AH5nN+nR9SPmC0rFHtzsS4lBQ7/dgOwtwVxYP7W9JPDMuRBkJ4KHmWKr036eJsj9g==
|
||||
dependencies:
|
||||
"@rushstack/node-core-library" "5.13.1"
|
||||
supports-color "~8.1.1"
|
||||
|
||||
"@rushstack/[email protected]":
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-5.0.1.tgz#e147394b5ce87ef79db95b5b4f155461d6f2c50e"
|
||||
integrity sha512-bsbUucn41UXrQK7wgM8CNM/jagBytEyJqXw/umtI8d68vFm1Jwxh1OtLrlW7uGZgjCWiiPH6ooUNa1aVsuVr3Q==
|
||||
dependencies:
|
||||
"@rushstack/terminal" "0.15.3"
|
||||
"@types/argparse" "1.0.38"
|
||||
argparse "~1.0.9"
|
||||
string-argv "~0.3.1"
|
||||
|
||||
"@types/[email protected]":
|
||||
version "1.0.38"
|
||||
resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9"
|
||||
integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==
|
||||
|
||||
"@types/[email protected]", "@types/estree@^1.0.0":
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8"
|
||||
integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==
|
||||
|
||||
"@types/[email protected]":
|
||||
version "22.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.12.0.tgz#bf8af3b2af0837b5a62a368756ff2b705ae0048c"
|
||||
integrity sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==
|
||||
dependencies:
|
||||
undici-types "~6.20.0"
|
||||
|
||||
"@volar/[email protected]", "@volar/language-core@~2.4.11":
|
||||
version "2.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.4.14.tgz#dac7573014d4f3bafb186cb16888ffea5698be71"
|
||||
integrity sha512-X6beusV0DvuVseaOEy7GoagS4rYHgDHnTrdOj5jeUb49fW5ceQyP9Ej5rBhqgz2wJggl+2fDbbojq1XKaxDi6w==
|
||||
dependencies:
|
||||
"@volar/source-map" "2.4.14"
|
||||
|
||||
"@volar/[email protected]":
|
||||
version "2.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.4.14.tgz#cdcecd533c2e767449b2414cc22327d2bda7ef95"
|
||||
integrity sha512-5TeKKMh7Sfxo8021cJfmBzcjfY1SsXsPMMjMvjY7ivesdnybqqS+GxGAoXHAOUawQTwtdUxgP65Im+dEmvWtYQ==
|
||||
|
||||
"@volar/typescript@^2.4.11":
|
||||
version "2.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.4.14.tgz#b99a1025dd6a8b751e96627ebcb0739ceed0e5f1"
|
||||
integrity sha512-p8Z6f/bZM3/HyCdRNFZOEEzts51uV8WHeN8Tnfnm2EBv6FDB2TQLzfVx7aJvnl8ofKAOnS64B2O8bImBFaauRw==
|
||||
dependencies:
|
||||
"@volar/language-core" "2.4.14"
|
||||
path-browserify "^1.0.1"
|
||||
vscode-uri "^3.0.8"
|
||||
|
||||
"@vue/[email protected]":
|
||||
version "3.5.16"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.16.tgz#2f95f4f17c16c09c57bbf64399075b921506630b"
|
||||
integrity sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.27.2"
|
||||
"@vue/shared" "3.5.16"
|
||||
entities "^4.5.0"
|
||||
estree-walker "^2.0.2"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
"@vue/compiler-dom@^3.5.0":
|
||||
version "3.5.16"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.16.tgz#151d8390252975c0b1a773029220fdfcfaa2d743"
|
||||
integrity sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.5.16"
|
||||
"@vue/shared" "3.5.16"
|
||||
|
||||
"@vue/compiler-vue2@^2.7.16":
|
||||
version "2.7.16"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz#2ba837cbd3f1b33c2bc865fbe1a3b53fb611e249"
|
||||
integrity sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==
|
||||
dependencies:
|
||||
de-indent "^1.0.2"
|
||||
he "^1.2.0"
|
||||
|
||||
"@vue/[email protected]":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.2.0.tgz#e48c54584f889f78b120ce10a050dfb316c7fcdf"
|
||||
integrity sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==
|
||||
dependencies:
|
||||
"@volar/language-core" "~2.4.11"
|
||||
"@vue/compiler-dom" "^3.5.0"
|
||||
"@vue/compiler-vue2" "^2.7.16"
|
||||
"@vue/shared" "^3.5.0"
|
||||
alien-signals "^0.4.9"
|
||||
minimatch "^9.0.3"
|
||||
muggle-string "^0.4.1"
|
||||
path-browserify "^1.0.1"
|
||||
|
||||
"@vue/[email protected]", "@vue/shared@^3.5.0":
|
||||
version "3.5.16"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.16.tgz#d5ea7671182742192938a4b4cbf86ef12bef7418"
|
||||
integrity sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==
|
||||
|
||||
acorn@^8.14.0:
|
||||
version "8.14.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb"
|
||||
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
|
||||
|
||||
ajv-draft-04@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz#3b64761b268ba0b9e668f0b41ba53fce0ad77fc8"
|
||||
integrity sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==
|
||||
|
||||
ajv-formats@~3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578"
|
||||
integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==
|
||||
dependencies:
|
||||
ajv "^8.0.0"
|
||||
|
||||
ajv@^8.0.0:
|
||||
version "8.17.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6"
|
||||
integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
fast-uri "^3.0.1"
|
||||
json-schema-traverse "^1.0.0"
|
||||
require-from-string "^2.0.2"
|
||||
|
||||
ajv@~8.12.0:
|
||||
version "8.12.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1"
|
||||
integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
json-schema-traverse "^1.0.0"
|
||||
require-from-string "^2.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@~8.13.0:
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.13.0.tgz#a3939eaec9fb80d217ddf0c3376948c023f28c91"
|
||||
integrity sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
json-schema-traverse "^1.0.0"
|
||||
require-from-string "^2.0.2"
|
||||
uri-js "^4.4.1"
|
||||
|
||||
alien-signals@^0.4.9:
|
||||
version "0.4.14"
|
||||
resolved "https://registry.yarnpkg.com/alien-signals/-/alien-signals-0.4.14.tgz#9ff8f72a272300a51692f54bd9bbbada78fbf539"
|
||||
integrity sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==
|
||||
|
||||
argparse@~1.0.9:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
|
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
compare-versions@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.1.tgz#7af3cc1099ba37d244b3145a9af5201b629148a9"
|
||||
integrity sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==
|
||||
|
||||
[email protected]:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||
|
||||
confbox@^0.1.8:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06"
|
||||
integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==
|
||||
|
||||
confbox@^0.2.1:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.2.2.tgz#8652f53961c74d9e081784beed78555974a9c110"
|
||||
integrity sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==
|
||||
|
||||
de-indent@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||
integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
|
||||
|
||||
debug@^4.4.0:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
|
||||
integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
entities@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||
|
||||
esbuild@^0.25.0:
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.5.tgz#71075054993fdfae76c66586f9b9c1f8d7edd430"
|
||||
integrity sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==
|
||||
optionalDependencies:
|
||||
"@esbuild/aix-ppc64" "0.25.5"
|
||||
"@esbuild/android-arm" "0.25.5"
|
||||
"@esbuild/android-arm64" "0.25.5"
|
||||
"@esbuild/android-x64" "0.25.5"
|
||||
"@esbuild/darwin-arm64" "0.25.5"
|
||||
"@esbuild/darwin-x64" "0.25.5"
|
||||
"@esbuild/freebsd-arm64" "0.25.5"
|
||||
"@esbuild/freebsd-x64" "0.25.5"
|
||||
"@esbuild/linux-arm" "0.25.5"
|
||||
"@esbuild/linux-arm64" "0.25.5"
|
||||
"@esbuild/linux-ia32" "0.25.5"
|
||||
"@esbuild/linux-loong64" "0.25.5"
|
||||
"@esbuild/linux-mips64el" "0.25.5"
|
||||
"@esbuild/linux-ppc64" "0.25.5"
|
||||
"@esbuild/linux-riscv64" "0.25.5"
|
||||
"@esbuild/linux-s390x" "0.25.5"
|
||||
"@esbuild/linux-x64" "0.25.5"
|
||||
"@esbuild/netbsd-arm64" "0.25.5"
|
||||
"@esbuild/netbsd-x64" "0.25.5"
|
||||
"@esbuild/openbsd-arm64" "0.25.5"
|
||||
"@esbuild/openbsd-x64" "0.25.5"
|
||||
"@esbuild/sunos-x64" "0.25.5"
|
||||
"@esbuild/win32-arm64" "0.25.5"
|
||||
"@esbuild/win32-ia32" "0.25.5"
|
||||
"@esbuild/win32-x64" "0.25.5"
|
||||
|
||||
estree-walker@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||
|
||||
exsolve@^1.0.1:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.0.5.tgz#1f5b6b4fe82ad6b28a173ccb955a635d77859dcf"
|
||||
integrity sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==
|
||||
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-uri@^3.0.1:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748"
|
||||
integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==
|
||||
|
||||
fdir@^6.4.4:
|
||||
version "6.4.5"
|
||||
resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.5.tgz#328e280f3a23699362f95f2e82acf978a0c0cb49"
|
||||
integrity sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==
|
||||
|
||||
fs-extra@~11.3.0:
|
||||
version "11.3.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d"
|
||||
integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^6.0.1"
|
||||
universalify "^2.0.0"
|
||||
|
||||
fsevents@~2.3.2, fsevents@~2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
function-bind@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
|
||||
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
|
||||
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||
version "4.2.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
|
||||
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
hasown@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
|
||||
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
|
||||
dependencies:
|
||||
function-bind "^1.1.2"
|
||||
|
||||
he@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
import-lazy@~4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153"
|
||||
integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==
|
||||
|
||||
is-core-module@^2.16.0:
|
||||
version "2.16.1"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
|
||||
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
|
||||
dependencies:
|
||||
hasown "^2.0.2"
|
||||
|
||||
jju@~1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a"
|
||||
integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==
|
||||
|
||||
json-schema-traverse@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
|
||||
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||
dependencies:
|
||||
universalify "^2.0.0"
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
kolorist@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.8.0.tgz#edddbbbc7894bc13302cdf740af6374d4a04743c"
|
||||
integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==
|
||||
|
||||
local-pkg@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-1.1.1.tgz#f5fe74a97a3bd3c165788ee08ca9fbe998dc58dd"
|
||||
integrity sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==
|
||||
dependencies:
|
||||
mlly "^1.7.4"
|
||||
pkg-types "^2.0.1"
|
||||
quansync "^0.2.8"
|
||||
|
||||
lodash@~4.17.15:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
lru-cache@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
|
||||
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
magic-string@^0.30.17:
|
||||
version "0.30.17"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
|
||||
integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||
|
||||
minimatch@^9.0.3:
|
||||
version "9.0.5"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
|
||||
integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimatch@~3.0.3:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1"
|
||||
integrity sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
mlly@^1.7.4:
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.4.tgz#3d7295ea2358ec7a271eaa5d000a0f84febe100f"
|
||||
integrity sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==
|
||||
dependencies:
|
||||
acorn "^8.14.0"
|
||||
pathe "^2.0.1"
|
||||
pkg-types "^1.3.0"
|
||||
ufo "^1.5.4"
|
||||
|
||||
ms@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
muggle-string@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328"
|
||||
integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==
|
||||
|
||||
nanoid@^3.3.11:
|
||||
version "3.3.11"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
|
||||
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
|
||||
|
||||
path-browserify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
|
||||
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
|
||||
|
||||
path-parse@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
pathe@^2.0.1, pathe@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716"
|
||||
integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==
|
||||
|
||||
picocolors@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
|
||||
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
|
||||
|
||||
picomatch@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
|
||||
integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
|
||||
|
||||
pkg-types@^1.3.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df"
|
||||
integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==
|
||||
dependencies:
|
||||
confbox "^0.1.8"
|
||||
mlly "^1.7.4"
|
||||
pathe "^2.0.1"
|
||||
|
||||
pkg-types@^2.0.1:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-2.1.0.tgz#70c9e1b9c74b63fdde749876ee0aa007ea9edead"
|
||||
integrity sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==
|
||||
dependencies:
|
||||
confbox "^0.2.1"
|
||||
exsolve "^1.0.1"
|
||||
pathe "^2.0.3"
|
||||
|
||||
postcss@^8.5.3:
|
||||
version "8.5.4"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.4.tgz#d61014ac00e11d5f58458ed7247d899bd65f99c0"
|
||||
integrity sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==
|
||||
dependencies:
|
||||
nanoid "^3.3.11"
|
||||
picocolors "^1.1.1"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
||||
|
||||
quansync@^0.2.8:
|
||||
version "0.2.10"
|
||||
resolved "https://registry.yarnpkg.com/quansync/-/quansync-0.2.10.tgz#32053cf166fa36511aae95fc49796116f2dc20e1"
|
||||
integrity sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==
|
||||
|
||||
require-from-string@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||
|
||||
resolve@~1.22.1, resolve@~1.22.2:
|
||||
version "1.22.10"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
|
||||
integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
|
||||
dependencies:
|
||||
is-core-module "^2.16.0"
|
||||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
rollup@^4.34.9:
|
||||
version "4.41.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.41.1.tgz#46ddc1b33cf1b0baa99320d3b0b4973dc2253b6a"
|
||||
integrity sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==
|
||||
dependencies:
|
||||
"@types/estree" "1.0.7"
|
||||
optionalDependencies:
|
||||
"@rollup/rollup-android-arm-eabi" "4.41.1"
|
||||
"@rollup/rollup-android-arm64" "4.41.1"
|
||||
"@rollup/rollup-darwin-arm64" "4.41.1"
|
||||
"@rollup/rollup-darwin-x64" "4.41.1"
|
||||
"@rollup/rollup-freebsd-arm64" "4.41.1"
|
||||
"@rollup/rollup-freebsd-x64" "4.41.1"
|
||||
"@rollup/rollup-linux-arm-gnueabihf" "4.41.1"
|
||||
"@rollup/rollup-linux-arm-musleabihf" "4.41.1"
|
||||
"@rollup/rollup-linux-arm64-gnu" "4.41.1"
|
||||
"@rollup/rollup-linux-arm64-musl" "4.41.1"
|
||||
"@rollup/rollup-linux-loongarch64-gnu" "4.41.1"
|
||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.41.1"
|
||||
"@rollup/rollup-linux-riscv64-gnu" "4.41.1"
|
||||
"@rollup/rollup-linux-riscv64-musl" "4.41.1"
|
||||
"@rollup/rollup-linux-s390x-gnu" "4.41.1"
|
||||
"@rollup/rollup-linux-x64-gnu" "4.41.1"
|
||||
"@rollup/rollup-linux-x64-musl" "4.41.1"
|
||||
"@rollup/rollup-win32-arm64-msvc" "4.41.1"
|
||||
"@rollup/rollup-win32-ia32-msvc" "4.41.1"
|
||||
"@rollup/rollup-win32-x64-msvc" "4.41.1"
|
||||
fsevents "~2.3.2"
|
||||
|
||||
semver@~7.5.4:
|
||||
version "7.5.4"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
|
||||
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
source-map-js@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
||||
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
||||
|
||||
source-map@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
|
||||
|
||||
string-argv@~0.3.1:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
|
||||
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
|
||||
|
||||
strip-json-comments@~3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
supports-color@~8.1.1:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
||||
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
supports-preserve-symlinks-flag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
tinyglobby@^0.2.13:
|
||||
version "0.2.14"
|
||||
resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.14.tgz#5280b0cf3f972b050e74ae88406c0a6a58f4079d"
|
||||
integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==
|
||||
dependencies:
|
||||
fdir "^6.4.4"
|
||||
picomatch "^4.0.2"
|
||||
|
||||
[email protected]:
|
||||
version "5.4.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372"
|
||||
integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==
|
||||
|
||||
[email protected]:
|
||||
version "5.8.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.2.tgz#8170b3702f74b79db2e5a96207c15e65807999e4"
|
||||
integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==
|
||||
|
||||
ufo@^1.5.4:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b"
|
||||
integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==
|
||||
|
||||
undici-types@~6.20.0:
|
||||
version "6.20.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
|
||||
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
|
||||
|
||||
universalify@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
|
||||
integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==
|
||||
|
||||
uri-js@^4.2.2, uri-js@^4.4.1:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
[email protected]:
|
||||
version "4.5.4"
|
||||
resolved "https://registry.yarnpkg.com/vite-plugin-dts/-/vite-plugin-dts-4.5.4.tgz#51b60aaaa760d9cf5c2bb3676c69d81910d6b08c"
|
||||
integrity sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==
|
||||
dependencies:
|
||||
"@microsoft/api-extractor" "^7.50.1"
|
||||
"@rollup/pluginutils" "^5.1.4"
|
||||
"@volar/typescript" "^2.4.11"
|
||||
"@vue/language-core" "2.2.0"
|
||||
compare-versions "^6.1.1"
|
||||
debug "^4.4.0"
|
||||
kolorist "^1.8.0"
|
||||
local-pkg "^1.0.0"
|
||||
magic-string "^0.30.17"
|
||||
|
||||
[email protected]:
|
||||
version "6.3.5"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-6.3.5.tgz#fec73879013c9c0128c8d284504c6d19410d12a3"
|
||||
integrity sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==
|
||||
dependencies:
|
||||
esbuild "^0.25.0"
|
||||
fdir "^6.4.4"
|
||||
picomatch "^4.0.2"
|
||||
postcss "^8.5.3"
|
||||
rollup "^4.34.9"
|
||||
tinyglobby "^0.2.13"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
vscode-uri@^3.0.8:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.1.0.tgz#dd09ec5a66a38b5c3fffc774015713496d14e09c"
|
||||
integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==
|
||||
|
||||
yallist@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||
@@ -48,32 +48,8 @@ frontend:
|
||||
cpu: 250m
|
||||
env:
|
||||
NEXT_PUBLIC_APP_ENV: review
|
||||
NEXT_PUBLIC_NETWORK_LOGO: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/base.svg
|
||||
NEXT_PUBLIC_NETWORK_ICON: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/base.svg
|
||||
NEXT_PUBLIC_FEATURED_NETWORKS: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/base-mainnet.json
|
||||
NEXT_PUBLIC_API_HOST: base.blockscout.com
|
||||
NEXT_PUBLIC_LOGOUT_URL: https://blockscoutcom.us.auth0.com/v2/logout
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://stats-l2-base-mainnet.k8s-prod-1.blockscout.com
|
||||
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND: "linear-gradient(136.9deg,rgb(107 94 236) 1.5%,rgb(0 82 255) 56.84%,rgb(82 62 231) 98.54%)"
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://mainnet.base.org
|
||||
NEXT_PUBLIC_WEB3_WALLETS: "['coinbase']"
|
||||
NEXT_PUBLIC_WEB3_DISABLE_ADD_TOKEN_TO_WALLET: true
|
||||
NEXT_PUBLIC_HOMEPAGE_CHARTS: "['daily_txs']"
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://visualizer.services.blockscout.com
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://contracts-info.services.blockscout.com
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://admin-rs.services.blockscout.com
|
||||
NEXT_PUBLIC_NAME_SERVICE_API_HOST: https://bens.services.blockscout.com
|
||||
NEXT_PUBLIC_METADATA_SERVICE_API_HOST: https://metadata.services.blockscout.com
|
||||
NEXT_PUBLIC_ROLLUP_TYPE: optimistic
|
||||
NEXT_PUBLIC_ROLLUP_L1_BASE_URL: https://eth.blockscout.com
|
||||
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL: https://app.optimism.io/bridge/withdraw
|
||||
NEXT_PUBLIC_GRAPHIQL_TRANSACTION: 0x4a0ed8ddf751a7cb5297f827699117b0f6d21a0b2907594d300dc9fed75c7e62
|
||||
NEXT_PUBLIC_USE_NEXT_JS_PROXY: true
|
||||
NEXT_PUBLIC_NAVIGATION_LAYOUT: horizontal
|
||||
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES: "['/blocks','/name-domains']"
|
||||
SKIP_ENVS_VALIDATION: true
|
||||
envFromSecret:
|
||||
NEXT_PUBLIC_AUTH0_CLIENT_ID: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_AUTH0_CLIENT_ID
|
||||
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID
|
||||
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
|
||||
NEXT_PUBLIC_OG_IMAGE_URL: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/base-mainnet.png
|
||||
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY: ref+vault://deployment-values/blockscout/eth-sepolia/testnet?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/RE_CAPTCHA_CLIENT_KEY
|
||||
|
||||
@@ -12,3 +12,4 @@
|
||||
| NEXT_PUBLIC_NETWORK_GOVERNANCE_TOKEN_SYMBOL | `string` | Network governance token symbol | - | - | `GNO` | v1.12.0 | v1.29.0 | Replaced by NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL |
|
||||
| NEXT_PUBLIC_SWAP_BUTTON_URL | `string` | Application ID in the marketplace or website URL | - | - | `uniswap` | v1.24.0 | v1.31.0 | Replaced by NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS |
|
||||
| NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME | `boolean` | Set to false if average block time is useless for the network | - | `true` | `false` | v1.0.x+ | v1.35.0 | Replaced by NEXT_PUBLIC_HOMEPAGE_STATS |
|
||||
| NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK | `number` | Indicates the block number when the Celo-type chain transitioned to L2. This is used to display links to the Epoch block page from a regular block page. | - | - | `26369280` | v1.37.0+ | v2.2.0 | Removed; configuration done on the API side |
|
||||
|
||||
+27
-2
@@ -76,6 +76,7 @@ All json-like values should be single-quoted. If it contains a hash (`#`) or a d
|
||||
- [Save on gas with GasHawk](#save-on-gas-with-gashawk)
|
||||
- [Rewards service API](#rewards-service-api)
|
||||
- [DEX pools](#dex-pools)
|
||||
- [Address 3rd party widgets](#address-3rd-party-widgets)
|
||||
- [3rd party services configuration](#external-services-configuration)
|
||||
|
||||
|
||||
@@ -192,7 +193,7 @@ The app version shown in the footer is derived from build-time ENV variables `NE
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| title | `string` | Title of link group | Required | - | `Company` |
|
||||
| links | `Array<{'text':string;'url':string;}>` | list of links | Required | - | `[{'text':'Homepage','url':'https://www.blockscout.com'}]` |
|
||||
| links | `Array<{'text':string;'url':string;'iconUrl'?:[string,string]}>` | An array contains a list of links in the column. Each link can optionally have an `icon_url` property, which should include an array of two external image URLs for light and dark themes, respectively. If only one URL is provided, it will be used for both color schemes. We expect the icons to be square, with a minimum size of 40px by 40px or in SVG format. | Required | - | `[{'text':'Homepage','url':'https://www.blockscout.com'}]` |
|
||||
|
||||
|
||||
|
||||
@@ -657,6 +658,7 @@ This feature allows name tags and other public tags for addresses.
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_METADATA_SERVICE_API_HOST | `string` | Metadata Service API endpoint url | Required | - | `https://metadata.services.blockscout.com` | v1.30.0+ |
|
||||
| NEXT_PUBLIC_METADATA_ADDRESS_TAGS_UPDATE_ENABLED | `boolean` | Enables requests to the Metadata Service to schedule an update for address tags after the user visits the address page in the app. | - | `true` | `false` | v2.2.0+ |
|
||||
|
||||
|
||||
|
||||
@@ -771,7 +773,6 @@ For blockchains that use the Celo platform. _Note_, that once the Celo mainnet b
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_CELO_ENABLED | `boolean` | Indicates that it is a Celo-based chain. | - | - | `true` | v1.37.0+ |
|
||||
| NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK | `number` | Indicates the block number when the Celo-type chain transitioned to L2. This is used to display links to the Epoch block page from a regular block page. | - | - | `26369280` | v1.37.0+ |
|
||||
|
||||
|
||||
|
||||
@@ -917,6 +918,30 @@ This feature enables Blockscout Merits program. It requires that the [My account
|
||||
|
||||
|
||||
|
||||
### Address 3rd party widgets
|
||||
|
||||
This feature allows to display widgets on the address page with data from 3rd party services.
|
||||
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS | `Array<string>` | Array of widget ids to be displayed | - | - | `['widget-1', 'widget-2']` | v2.2.0+ |
|
||||
| NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL | `string` | URL of configuration file (`.json` format only) which contains mapping of widget names to their configuration. See [below](#address-3rd-party-widget-configuration-properties) list of available properties for a widget. | - | - | `https://example.com/address_3rd_party_widgets_config.json` | v2.2.0+ |
|
||||
|
||||
#### Address 3rd party widget configuration properties
|
||||
|
||||
| Property | Type | Description | Compulsoriness | Example value |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| name | `string` | Displayed name of the widget | Required | - | `'Widget'` |
|
||||
| url | `string` | Link URL for widget card. Can contain `{address}`, `{addressLowercase}` and `{chainId}` variables | Required | - | `'https://example.com/widget/{address}?chainId={chainId}'` |
|
||||
| icon | `string` | Widget icon URL | Required | - | `'https://example.com/icon.svg'` |
|
||||
| title | `string` | Title of displayed data | Required | - | `'Multichain balance'` |
|
||||
| hint | `string` | Hint for displayed data | - | - | `'Widget hint'` |
|
||||
| valuePath | `string` | Path to the field in the API response that contains the value to be displayed | Required | - | `'result.balance'` |
|
||||
| pages | `Array<'eoa' \| 'contract' \| 'token'>` | List of pages where the widget should be displayed | Required | - | `['eoa']` |
|
||||
| chainIds | `Record<string, string>` | Mapping of chain IDs to custom values that will be used in `url` template | - | - | `{'1': 'eth', '10': 'op'}` |
|
||||
|
||||
|
||||
|
||||
### Badge claim link
|
||||
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
|
||||
|
||||
Vendored
+2
@@ -1,3 +1,4 @@
|
||||
import type { MultichainConfig } from 'types/multichain';
|
||||
import type { WalletProvider } from 'types/web3';
|
||||
|
||||
type CPreferences = {
|
||||
@@ -19,6 +20,7 @@ declare global {
|
||||
};
|
||||
abkw: string;
|
||||
__envs: Record<string, string>;
|
||||
__multichainConfig: MultichainConfig;
|
||||
}
|
||||
|
||||
namespace NodeJS {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.164.859a9.3 9.3 0 0 1 8.3 2.457l.047.046c.136.134.268.272.395.415l.03.033c.207.234.403.478.587.733l.039.055.15.214c.087.131.17.266.25.401.15.252.29.51.415.773.012.024.022.049.033.073.084.18.161.362.233.546l.03.08a9.3 9.3 0 0 1 .607 3.297l-.012.46a9.301 9.301 0 0 1-2.395 5.781l-.317.334a9.3 9.3 0 0 1-6.114 2.712l-.461.012A9.3 9.3 0 0 1 5.105 17.9l-.29-.187a9.303 9.303 0 0 1-.819-.615l-.055-.049a9.33 9.33 0 0 1-.438-.397l-.098-.098a8.814 8.814 0 0 1-.351-.371l-.078-.088a9.32 9.32 0 0 1-.16-.188l-.062-.075a9.397 9.397 0 0 1-.294-.383A9.297 9.297 0 0 1 8.164.859Zm1.817 1.509a7.617 7.617 0 0 0-3.994 1.13l-.237.153A7.616 7.616 0 0 0 3.06 6.81l-.113.259a7.615 7.615 0 0 0-.433 4.398l.06.277a7.613 7.613 0 0 0 2.024 3.622l.203.196a7.615 7.615 0 0 0 3.695 1.888l.278.05a7.614 7.614 0 0 0 4.12-.484l.26-.112a7.615 7.615 0 0 0 3.159-2.692l.152-.237a7.616 7.616 0 0 0 1.13-3.993l-.008-.378a7.614 7.614 0 0 0-1.962-4.732l-.26-.274a7.614 7.614 0 0 0-5.005-2.22l-.378-.01Zm.083 1.138c.192.02.374.104.512.242l.056.062c.123.15.191.339.191.534v5.29l3.631 3.626c.079.078.142.17.185.274l.027.078c.024.08.037.162.037.245l-.005.084a.84.84 0 0 1-.032.162l-.027.078a.852.852 0 0 1-.129.213l-.057.062a.837.837 0 0 1-.199.146l-.075.034a.841.841 0 0 1-.566.029l-.079-.029a.842.842 0 0 1-.274-.18l-3.877-3.877a.853.853 0 0 1-.146-.2l-.036-.075a.846.846 0 0 1-.063-.323V4.344c0-.223.09-.438.247-.596l.061-.055a.844.844 0 0 1 .535-.192l.083.005Z" fill="currentColor"/>
|
||||
<path d="M8.164.859a9.3 9.3 0 0 1 8.3 2.457l.047.046c.136.134.268.272.395.415l.03.033c.207.234.403.478.587.733l.039.055.15.214c.087.131.17.266.25.401.15.252.29.51.415.773.012.024.022.049.033.073.084.18.161.362.233.546l.03.08a9.3 9.3 0 0 1 .607 3.297l-.012.46a9.301 9.301 0 0 1-2.395 5.781l-.317.334a9.3 9.3 0 0 1-6.114 2.712l-.461.012A9.3 9.3 0 0 1 5.105 17.9l-.29-.187a9.303 9.303 0 0 1-.819-.615l-.055-.049a9.33 9.33 0 0 1-.438-.397l-.098-.098a8.814 8.814 0 0 1-.351-.371l-.078-.088a9.32 9.32 0 0 1-.16-.188l-.062-.075a9.397 9.397 0 0 1-.294-.383A9.297 9.297 0 0 1 8.164.859Zm1.817 1.509a7.617 7.617 0 0 0-3.994 1.13l-.237.153A7.616 7.616 0 0 0 3.06 6.81l-.113.259a7.615 7.615 0 0 0-.433 4.398l.06.277a7.613 7.613 0 0 0 2.024 3.622l.203.196a7.615 7.615 0 0 0 3.695 1.888l.278.05a7.614 7.614 0 0 0 4.12-.484l.26-.112a7.615 7.615 0 0 0 3.159-2.692l.152-.237a7.616 7.616 0 0 0 1.13-3.993l-.008-.378a7.614 7.614 0 0 0-1.962-4.732l-.26-.274a7.614 7.614 0 0 0-5.005-2.22l-.378-.01Zm.083 1.138c.192.02.374.104.512.242l.056.062c.123.15.191.339.191.534v5.29l3.631 3.626a.83.83 0 0 1 .185.274l.027.078a.85.85 0 0 1 .037.245l-.005.084a.84.84 0 0 1-.032.162l-.027.078a.852.852 0 0 1-.129.213l-.057.062a.837.837 0 0 1-.199.146l-.075.034a.841.841 0 0 1-.566.029l-.079-.029a.842.842 0 0 1-.274-.18l-3.877-3.877a.853.853 0 0 1-.146-.2l-.036-.075a.846.846 0 0 1-.063-.323V4.344c0-.223.09-.438.247-.596l.061-.055a.844.844 0 0 1 .535-.192l.083.005Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
+3
-2
@@ -1,3 +1,4 @@
|
||||
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.125 6.906a1.257 1.257 0 0 0 .5-1V3.125a1.25 1.25 0 0 0-1.25-1.25h-8.75a1.25 1.25 0 0 0-1.25 1.25v2.813a1.258 1.258 0 0 0 .5 1L6.289 8l2.672 2-4.086 3.063a1.258 1.258 0 0 0-.5 1v2.812a1.25 1.25 0 0 0 1.25 1.25h8.75a1.25 1.25 0 0 0 1.25-1.25v-2.781a1.257 1.257 0 0 0-.5-1L11.039 10l1.774-1.344 2.312-1.75Zm-9.5-3.781h8.75v2.781l-.453.344H6.039l-.414-.313V3.126Zm8.75 10.969v2.781h-8.75v-2.813l3.75-2.812v1.875a.625.625 0 1 0 1.25 0v-1.867l3.75 2.836Z" fill="currentColor"/>
|
||||
<svg viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21.052 4.708c.415.037.82.204 1.141.493l.132.132c.293.323.47.746.47 1.206v3.43a1.785 1.785 0 0 1-.128.654l-.096.201a1.875 1.875 0 0 1-.58.635l-.003.002L16.796 15l5.192 3.54.014.01.145.11.013.012c.163.14.304.31.411.504l.096.201c.083.206.127.428.129.654v3.43l-.01.195a1.8 1.8 0 0 1-.46 1.012l-.133.132c-.32.29-.726.455-1.141.492l-.179.008H8.923c-.417 0-.833-.13-1.177-.384l-.142-.116a1.821 1.821 0 0 1-.567-.978l-.026-.166-.002-.016L7 23.478v-3.483l.001-.021.014-.188.002-.018.03-.166c.038-.162.098-.319.179-.464l.01-.016.098-.155.01-.015.101-.128c.104-.12.223-.225.352-.314l.016-.012L12.986 15l-5.174-3.498-.015-.012a1.889 1.889 0 0 1-.453-.442l-.118-.186a1.799 1.799 0 0 1-.21-.63L7 10.008V6.539a1.8 1.8 0 0 1 .604-1.338l.142-.116c.343-.254.76-.385 1.177-.385h11.95l.179.008ZM9.139 20.182v2.98h11.52v-2.941l-4.691-3.198v1.823a1.07 1.07 0 0 1-.96 1.063l-.11.006a1.07 1.07 0 0 1-1.069-1.07v-1.832l-4.69 3.169Zm-.121.082h.002l.006-.006-.008.006Zm5.877-6.557 2.176-1.483H12.7l2.196 1.483Zm-5.756-3.89.395.268H20.21l.45-.307v-2.94H9.138v2.98Z" fill="currentColor"/>
|
||||
<path d="M21.052 4.708c.415.037.82.204 1.141.493l.132.132c.293.323.47.746.47 1.206v3.43a1.785 1.785 0 0 1-.128.654l-.096.201a1.875 1.875 0 0 1-.58.635l-.003.002L16.796 15l5.192 3.54.014.01.145.11.013.012c.163.14.304.31.411.504l.096.201c.083.206.127.428.129.654v3.43l-.01.195a1.8 1.8 0 0 1-.46 1.012l-.133.132c-.32.29-.726.455-1.141.492l-.179.008H8.923c-.417 0-.833-.13-1.177-.384l-.142-.116a1.821 1.821 0 0 1-.567-.978l-.026-.166-.002-.016L7 23.478v-3.483l.001-.021.014-.188.002-.018.03-.166c.038-.162.098-.319.179-.464l.01-.016.098-.155.01-.015.101-.128c.104-.12.223-.225.352-.314l.016-.012L12.986 15l-5.174-3.498-.015-.012a1.889 1.889 0 0 1-.453-.442l-.118-.186a1.799 1.799 0 0 1-.21-.63L7 10.008V6.539a1.8 1.8 0 0 1 .604-1.338l.142-.116c.343-.254.76-.385 1.177-.385h11.95l.179.008ZM9.139 20.182v2.98h11.52v-2.941l-4.691-3.198v1.823a1.07 1.07 0 0 1-.96 1.063l-.11.006a1.07 1.07 0 0 1-1.069-1.07v-1.832l-4.69 3.169Zm-.121.082h.002l.006-.006-.008.006Zm5.877-6.557 2.176-1.483H12.7l2.196 1.483Zm-5.756-3.89.395.268H20.21l.45-.307v-2.94H9.138v2.98Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 567 B After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.125 6.906a1.257 1.257 0 0 0 .5-1V3.125a1.25 1.25 0 0 0-1.25-1.25h-8.75a1.25 1.25 0 0 0-1.25 1.25v2.813a1.258 1.258 0 0 0 .5 1L6.289 8l2.672 2-4.086 3.063a1.258 1.258 0 0 0-.5 1v2.812a1.25 1.25 0 0 0 1.25 1.25h8.75a1.25 1.25 0 0 0 1.25-1.25v-2.781a1.257 1.257 0 0 0-.5-1L11.039 10l1.774-1.344 2.312-1.75Zm-9.5-3.781h8.75v2.781l-.453.344H6.039l-.414-.313V3.126Zm8.75 10.969v2.781h-8.75v-2.813l3.75-2.812v1.875a.625.625 0 1 0 1.25 0v-1.867l3.75 2.836Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 567 B |
+5
-2
@@ -1,5 +1,8 @@
|
||||
export async function register() {
|
||||
if (process.env.NEXT_RUNTIME === 'nodejs' && process.env.NEXT_OPEN_TELEMETRY_ENABLED === 'true') {
|
||||
await import('./instrumentation.node');
|
||||
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
||||
if (process.env.NEXT_OPEN_TELEMETRY_ENABLED === 'true') {
|
||||
await import('./instrumentation.node');
|
||||
}
|
||||
await import('./startup.node');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { AddressMetadataInfoFormatted, AddressMetadataTagFormatted } from '
|
||||
|
||||
import config from 'configs/app';
|
||||
import useApiQuery from 'lib/api/useApiQuery';
|
||||
import { useMultichainContext } from 'lib/contexts/multichain';
|
||||
|
||||
import parseMetaPayload from './parseMetaPayload';
|
||||
|
||||
@@ -9,14 +10,18 @@ export default function useAddressMetadataInfoQuery(addresses: Array<string>, is
|
||||
|
||||
const resource = 'metadata:info';
|
||||
|
||||
const multichainContext = useMultichainContext();
|
||||
const feature = multichainContext?.chain?.config.features.addressMetadata || config.features.addressMetadata;
|
||||
const chainId = multichainContext?.chain?.config.chain.id || config.chain.id;
|
||||
|
||||
return useApiQuery<typeof resource, unknown, AddressMetadataInfoFormatted>(resource, {
|
||||
queryParams: {
|
||||
addresses,
|
||||
chainId: config.chain.id,
|
||||
chainId,
|
||||
tagsLimit: '20',
|
||||
},
|
||||
queryOptions: {
|
||||
enabled: isEnabled && addresses.length > 0 && config.features.addressMetadata.isEnabled,
|
||||
enabled: isEnabled && addresses.length > 0 && feature.isEnabled && Boolean(chainId),
|
||||
select: (data) => {
|
||||
const addresses = Object.entries(data.addresses)
|
||||
.map(([ address, { tags, reputation } ]) => {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { AddressCounters } from 'types/api/address';
|
||||
|
||||
import config from 'configs/app';
|
||||
import useApiFetch from 'lib/api/useApiFetch';
|
||||
|
||||
const feature = config.features.addressMetadata;
|
||||
|
||||
interface Params {
|
||||
address: string | undefined;
|
||||
counters: AddressCounters | undefined;
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
const TXS_THRESHOLD = 500;
|
||||
|
||||
export default function useAddressMetadataInitUpdate({ address, counters, isEnabled }: Params) {
|
||||
|
||||
const apiFetch = useApiFetch();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (
|
||||
feature.isEnabled &&
|
||||
feature.isAddressTagsUpdateEnabled &&
|
||||
address &&
|
||||
isEnabled &&
|
||||
counters?.transactions_count && Number(counters.transactions_count) > TXS_THRESHOLD
|
||||
) {
|
||||
apiFetch('metadata:address_submit', {
|
||||
fetchParams: {
|
||||
method: 'POST',
|
||||
body: {
|
||||
addresses: [ address ],
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [ address, apiFetch, counters?.transactions_count, isEnabled ]);
|
||||
}
|
||||
+4
-1
@@ -1,5 +1,7 @@
|
||||
import { compile } from 'path-to-regexp';
|
||||
|
||||
import type { ChainConfig } from 'types/multichain';
|
||||
|
||||
import config from 'configs/app';
|
||||
|
||||
import getResourceParams from './getResourceParams';
|
||||
@@ -11,8 +13,9 @@ export default function buildUrl<R extends ResourceName>(
|
||||
pathParams?: ResourcePathParams<R>,
|
||||
queryParams?: Record<string, string | Array<string> | number | boolean | null | undefined>,
|
||||
noProxy?: boolean,
|
||||
chain?: ChainConfig,
|
||||
): string {
|
||||
const { api, resource } = getResourceParams(resourceFullName);
|
||||
const { api, resource } = getResourceParams(resourceFullName, chain);
|
||||
const baseUrl = !noProxy && isNeedProxy() ? config.app.baseUrl : api.endpoint;
|
||||
const basePath = api.basePath ?? '';
|
||||
const path = !noProxy && isNeedProxy() ? '/node-api/proxy' + basePath + resource.path : basePath + resource.path;
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
import type { ApiName, ApiResource } from './types';
|
||||
import type { ChainConfig } from 'types/multichain';
|
||||
|
||||
import config from 'configs/app';
|
||||
|
||||
import type { ResourceName } from './resources';
|
||||
import { RESOURCES } from './resources';
|
||||
|
||||
export default function getResourceParams(resourceFullName: ResourceName) {
|
||||
export default function getResourceParams(resourceFullName: ResourceName, chain?: ChainConfig) {
|
||||
const [ apiName, resourceName ] = resourceFullName.split(':') as [ ApiName, string ];
|
||||
const apiConfig = config.apis[apiName];
|
||||
|
||||
const apiConfig = (() => {
|
||||
if (chain) {
|
||||
return chain.config.apis[apiName];
|
||||
}
|
||||
|
||||
return config.apis[apiName];
|
||||
})();
|
||||
|
||||
if (!apiConfig) {
|
||||
throw new Error(`API config for ${ apiName } not found`);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import appConfig from 'configs/app';
|
||||
|
||||
export default function getSocketUrl(config: typeof appConfig = appConfig) {
|
||||
return `${ config.apis.general.socketEndpoint }${ config.apis.general.basePath ?? '' }/socket/v2`;
|
||||
}
|
||||
@@ -10,6 +10,8 @@ import { GENERAL_API_RESOURCES } from './services/general';
|
||||
import type { GeneralApiResourceName, GeneralApiResourcePayload, GeneralApiPaginationFilters, GeneralApiPaginationSorting } from './services/general';
|
||||
import type { MetadataApiResourceName, MetadataApiResourcePayload } from './services/metadata';
|
||||
import { METADATA_API_RESOURCES } from './services/metadata';
|
||||
import type { MultichainApiResourceName, MultichainApiResourcePayload } from './services/multichain';
|
||||
import { MULTICHAIN_API_RESOURCES } from './services/multichain';
|
||||
import type { RewardsApiResourceName, RewardsApiResourcePayload } from './services/rewards';
|
||||
import { REWARDS_API_RESOURCES } from './services/rewards';
|
||||
import type { StatsApiResourceName, StatsApiResourcePayload } from './services/stats';
|
||||
@@ -30,6 +32,7 @@ export const RESOURCES = {
|
||||
contractInfo: CONTRACT_INFO_API_RESOURCES,
|
||||
general: GENERAL_API_RESOURCES,
|
||||
metadata: METADATA_API_RESOURCES,
|
||||
multichain: MULTICHAIN_API_RESOURCES,
|
||||
rewards: REWARDS_API_RESOURCES,
|
||||
stats: STATS_API_RESOURCES,
|
||||
tac: TAC_OPERATION_LIFECYCLE_API_RESOURCES,
|
||||
@@ -51,6 +54,7 @@ R extends BensApiResourceName ? BensApiResourcePayload<R> :
|
||||
R extends ContractInfoApiResourceName ? ContractInfoApiResourcePayload<R> :
|
||||
R extends GeneralApiResourceName ? GeneralApiResourcePayload<R> :
|
||||
R extends MetadataApiResourceName ? MetadataApiResourcePayload<R> :
|
||||
R extends MultichainApiResourceName ? MultichainApiResourcePayload<R> :
|
||||
R extends RewardsApiResourceName ? RewardsApiResourcePayload<R> :
|
||||
R extends StatsApiResourceName ? StatsApiResourcePayload<R> :
|
||||
R extends TacOperationLifecycleApiResourceName ? TacOperationLifecycleApiResourcePayload<R> :
|
||||
|
||||
@@ -116,7 +116,7 @@ export const GENERAL_API_ADDRESS_RESOURCES = {
|
||||
paginated: true,
|
||||
},
|
||||
address_epoch_rewards: {
|
||||
path: '/api/v2/addresses/:hash/election-rewards',
|
||||
path: '/api/v2/addresses/:hash/celo/election-rewards',
|
||||
pathParams: [ 'hash' as const ],
|
||||
filterFields: [],
|
||||
paginated: true,
|
||||
@@ -125,6 +125,33 @@ export const GENERAL_API_ADDRESS_RESOURCES = {
|
||||
path: '/api/v2/proxy/3dparty/xname/addresses/:hash',
|
||||
pathParams: [ 'hash' as const ],
|
||||
},
|
||||
address_3rd_party_info: {
|
||||
path: '/api/v2/proxy/3dparty/:name',
|
||||
pathParams: [ 'name' as const ],
|
||||
filterFields: [ 'address' as const, 'chain_id' as const ],
|
||||
},
|
||||
|
||||
// CSV EXPORTS
|
||||
address_csv_export_txs: {
|
||||
path: '/api/v2/addresses/:hash/transactions/csv',
|
||||
pathParams: [ 'hash' as const ],
|
||||
},
|
||||
address_csv_export_internal_txs: {
|
||||
path: '/api/v2/addresses/:hash/internal-transactions/csv',
|
||||
pathParams: [ 'hash' as const ],
|
||||
},
|
||||
address_csv_export_token_transfers: {
|
||||
path: '/api/v2/addresses/:hash/token-transfers/csv',
|
||||
pathParams: [ 'hash' as const ],
|
||||
},
|
||||
address_csv_export_logs: {
|
||||
path: '/api/v2/addresses/:hash/logs/csv',
|
||||
pathParams: [ 'hash' as const ],
|
||||
},
|
||||
address_csv_export_celo_election_rewards: {
|
||||
path: '/api/v2/addresses/:hash/celo/election-rewards/csv',
|
||||
pathParams: [ 'hash' as const ],
|
||||
},
|
||||
} satisfies Record<string, ApiResource>;
|
||||
|
||||
export type GeneralApiAddressResourceName = `general:${ keyof typeof GENERAL_API_ADDRESS_RESOURCES }`;
|
||||
@@ -149,6 +176,7 @@ R extends 'general:address_collections' ? AddressCollectionsResponse :
|
||||
R extends 'general:address_withdrawals' ? AddressWithdrawalsResponse :
|
||||
R extends 'general:address_epoch_rewards' ? AddressEpochRewardsResponse :
|
||||
R extends 'general:address_xstar_score' ? AddressXStarResponse :
|
||||
R extends 'general:address_3rd_party_info' ? unknown :
|
||||
never;
|
||||
/* eslint-enable @stylistic/indent */
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ import type {
|
||||
BlockFilters,
|
||||
BlockWithdrawalsResponse,
|
||||
BlockCountdownResponse,
|
||||
BlockEpoch,
|
||||
BlockEpochElectionRewardDetailsResponse,
|
||||
BlockInternalTransactionsResponse,
|
||||
} from 'types/api/block';
|
||||
import type { TTxsWithBlobsFilters } from 'types/api/txsFilters';
|
||||
@@ -39,17 +37,6 @@ export const GENERAL_API_BLOCK_RESOURCES = {
|
||||
filterFields: [],
|
||||
paginated: true,
|
||||
},
|
||||
block_epoch: {
|
||||
path: '/api/v2/blocks/:height_or_hash/epoch',
|
||||
pathParams: [ 'height_or_hash' as const ],
|
||||
filterFields: [],
|
||||
},
|
||||
block_election_rewards: {
|
||||
path: '/api/v2/blocks/:height_or_hash/election-rewards/:reward_type',
|
||||
pathParams: [ 'height_or_hash' as const, 'reward_type' as const ],
|
||||
filterFields: [],
|
||||
paginated: true,
|
||||
},
|
||||
} satisfies Record<string, ApiResource>;
|
||||
|
||||
export type GeneralApiBlockResourceName = `general:${ keyof typeof GENERAL_API_BLOCK_RESOURCES }`;
|
||||
@@ -62,8 +49,6 @@ R extends 'general:block_countdown' ? BlockCountdownResponse :
|
||||
R extends 'general:block_txs' ? BlockTransactionsResponse :
|
||||
R extends 'general:block_internal_txs' ? BlockInternalTransactionsResponse :
|
||||
R extends 'general:block_withdrawals' ? BlockWithdrawalsResponse :
|
||||
R extends 'general:block_epoch' ? BlockEpoch :
|
||||
R extends 'general:block_election_rewards' ? BlockEpochElectionRewardDetailsResponse :
|
||||
never;
|
||||
/* eslint-enable @stylistic/indent */
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ import type {
|
||||
import type { Blob } from 'types/api/blobs';
|
||||
import type { Block } from 'types/api/block';
|
||||
import type { ChartMarketResponse, ChartSecondaryCoinPriceResponse, ChartTransactionResponse } from 'types/api/charts';
|
||||
import type { BackendVersionConfig, CsvExportConfig } from 'types/api/configs';
|
||||
import type { BackendVersionConfig, CeloConfig, CsvExportConfig } from 'types/api/configs';
|
||||
import type { CeloEpochDetails, CeloEpochElectionRewardDetailsResponse, CeloEpochListResponse } from 'types/api/epochs';
|
||||
import type { IndexingStatus } from 'types/api/indexingStatus';
|
||||
import type { NovesAccountHistoryResponse, NovesDescribeTxsResponse, NovesResponseData } from 'types/api/noves';
|
||||
import type {
|
||||
@@ -181,6 +182,23 @@ export const GENERAL_API_MISC_RESOURCES = {
|
||||
pathParams: [ 'hash' as const ],
|
||||
},
|
||||
|
||||
// EPOCHS
|
||||
epochs_celo: {
|
||||
path: '/api/v2/celo/epochs',
|
||||
filterFields: [],
|
||||
paginated: true,
|
||||
},
|
||||
epoch_celo: {
|
||||
path: '/api/v2/celo/epochs/:number',
|
||||
pathParams: [ 'number' as const ],
|
||||
},
|
||||
epoch_celo_election_rewards: {
|
||||
path: '/api/v2/celo/epochs/:number/election-rewards/:reward_type',
|
||||
pathParams: [ 'number' as const, 'reward_type' as const ],
|
||||
filterFields: [],
|
||||
paginated: true,
|
||||
},
|
||||
|
||||
// ADVANCED FILTER
|
||||
advanced_filter: {
|
||||
path: '/api/v2/advanced-filters',
|
||||
@@ -224,11 +242,8 @@ export const GENERAL_API_MISC_RESOURCES = {
|
||||
config_csv_export: {
|
||||
path: '/api/v2/config/csv-export',
|
||||
},
|
||||
|
||||
// CSV EXPORT
|
||||
csv_export_token_holders: {
|
||||
path: '/api/v2/tokens/:hash/holders/csv',
|
||||
pathParams: [ 'hash' as const ],
|
||||
config_celo: {
|
||||
path: '/api/v2/config/celo',
|
||||
},
|
||||
|
||||
// OTHER
|
||||
@@ -261,6 +276,7 @@ R extends 'general:search' ? SearchResult :
|
||||
R extends 'general:search_check_redirect' ? SearchRedirectResult :
|
||||
R extends 'general:config_backend_version' ? BackendVersionConfig :
|
||||
R extends 'general:config_csv_export' ? CsvExportConfig :
|
||||
R extends 'general:config_celo' ? CeloConfig :
|
||||
R extends 'general:blob' ? Blob :
|
||||
R extends 'general:validators_stability' ? ValidatorsStabilityResponse :
|
||||
R extends 'general:validators_stability_counters' ? ValidatorsStabilityCountersResponse :
|
||||
@@ -268,6 +284,9 @@ R extends 'general:validators_blackfort' ? ValidatorsBlackfortResponse :
|
||||
R extends 'general:validators_blackfort_counters' ? ValidatorsBlackfortCountersResponse :
|
||||
R extends 'general:validators_zilliqa' ? ValidatorsZilliqaResponse :
|
||||
R extends 'general:validator_zilliqa' ? ValidatorZilliqa :
|
||||
R extends 'general:epochs_celo' ? CeloEpochListResponse :
|
||||
R extends 'general:epoch_celo' ? CeloEpochDetails :
|
||||
R extends 'general:epoch_celo_election_rewards' ? CeloEpochElectionRewardDetailsResponse :
|
||||
R extends 'general:user_ops' ? UserOpsResponse :
|
||||
R extends 'general:user_op' ? UserOp :
|
||||
R extends 'general:user_ops_account' ? UserOpsAccount :
|
||||
|
||||
@@ -49,6 +49,10 @@ export const GENERAL_API_TOKEN_RESOURCES = {
|
||||
filterFields: [ 'q' as const, 'chain_ids' as const ],
|
||||
paginated: true,
|
||||
},
|
||||
token_csv_export_holders: {
|
||||
path: '/api/v2/tokens/:hash/holders/csv',
|
||||
pathParams: [ 'hash' as const ],
|
||||
},
|
||||
|
||||
// TOKEN INSTANCE
|
||||
token_instance: {
|
||||
|
||||
@@ -2,21 +2,6 @@ import type { ApiResource } from '../../types';
|
||||
import type { BlockCountdownResponse } from 'types/api/block';
|
||||
|
||||
export const GENERAL_API_V1_RESOURCES = {
|
||||
csv_export_txs: {
|
||||
path: '/api/v1/transactions-csv',
|
||||
},
|
||||
csv_export_internal_txs: {
|
||||
path: '/api/v1/internal-transactions-csv',
|
||||
},
|
||||
csv_export_token_transfers: {
|
||||
path: '/api/v1/token-transfers-csv',
|
||||
},
|
||||
csv_export_logs: {
|
||||
path: '/api/v1/logs-csv',
|
||||
},
|
||||
csv_export_epoch_rewards: {
|
||||
path: '/api/v1/celo-election-rewards-csv',
|
||||
},
|
||||
graphql: {
|
||||
path: '/api/v1/graphql',
|
||||
},
|
||||
|
||||
@@ -11,6 +11,9 @@ export const METADATA_API_RESOURCES = {
|
||||
public_tag_types: {
|
||||
path: '/api/v1/public-tag-types',
|
||||
},
|
||||
address_submit: {
|
||||
path: '/api/v1/addresses\\:submit',
|
||||
},
|
||||
} satisfies Record<string, ApiResource>;
|
||||
|
||||
export type MetadataApiResourceName = `metadata:${ keyof typeof METADATA_API_RESOURCES }`;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { ApiResource } from '../types';
|
||||
import type * as multichain from '@blockscout/multichain-aggregator-types';
|
||||
|
||||
export const MULTICHAIN_API_RESOURCES = {
|
||||
interop_messages: {
|
||||
path: '/api/v1/interop/messages',
|
||||
paginated: true,
|
||||
},
|
||||
} satisfies Record<string, ApiResource>;
|
||||
|
||||
export type MultichainApiResourceName = `multichain:${ keyof typeof MULTICHAIN_API_RESOURCES }`;
|
||||
|
||||
/* eslint-disable @stylistic/indent */
|
||||
export type MultichainApiResourcePayload<R extends MultichainApiResourceName> =
|
||||
R extends 'multichain:interop_messages' ? multichain.ListInteropMessagesResponse :
|
||||
never;
|
||||
/* eslint-enable @stylistic/indent */
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
export type ApiName = 'general' | 'admin' | 'bens' | 'contractInfo' | 'metadata' | 'rewards' | 'stats' | 'visualize' | 'tac';
|
||||
export type ApiName = 'general' | 'admin' | 'bens' | 'contractInfo' | 'metadata' | 'multichain' | 'rewards' | 'stats' | 'tac' | 'visualize';
|
||||
|
||||
export interface ApiResource {
|
||||
path: string;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { omit, pickBy } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { CsrfData } from 'types/client/account';
|
||||
import type { ChainConfig } from 'types/multichain';
|
||||
|
||||
import config from 'configs/app';
|
||||
import isBodyAllowed from 'lib/api/isBodyAllowed';
|
||||
@@ -21,21 +22,23 @@ export interface Params<R extends ResourceName> {
|
||||
queryParams?: Record<string, string | Array<string> | number | boolean | undefined | null>;
|
||||
fetchParams?: Pick<FetchParams, 'body' | 'method' | 'signal' | 'headers'>;
|
||||
logError?: boolean;
|
||||
chain?: ChainConfig;
|
||||
}
|
||||
|
||||
export default function useApiFetch() {
|
||||
const fetch = useFetch();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { token: csrfToken } = queryClient.getQueryData<CsrfData>(getResourceKey('general:csrf')) || {};
|
||||
|
||||
return React.useCallback(<R extends ResourceName, SuccessType = unknown, ErrorType = unknown>(
|
||||
resourceName: R,
|
||||
{ pathParams, queryParams, fetchParams, logError }: Params<R> = {},
|
||||
{ pathParams, queryParams, fetchParams, logError, chain }: Params<R> = {},
|
||||
) => {
|
||||
const apiToken = cookies.get(cookies.NAMES.API_TOKEN);
|
||||
|
||||
const { api, apiName, resource } = getResourceParams(resourceName);
|
||||
const url = buildUrl(resourceName, pathParams, queryParams);
|
||||
const { api, apiName, resource } = getResourceParams(resourceName, chain);
|
||||
const url = buildUrl(resourceName, pathParams, queryParams, undefined, chain);
|
||||
const withBody = isBodyAllowed(fetchParams?.method);
|
||||
const headers = pickBy({
|
||||
'x-endpoint': api.endpoint && apiName !== 'general' && isNeedProxy() ? api.endpoint : undefined,
|
||||
|
||||
+16
-6
@@ -1,6 +1,8 @@
|
||||
import type { UseQueryOptions } from '@tanstack/react-query';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import multichainConfig from 'configs/multichain';
|
||||
import { useMultichainContext } from 'lib/contexts/multichain';
|
||||
import type { Params as FetchParams } from 'lib/hooks/useFetch';
|
||||
|
||||
import type { ResourceError, ResourceName, ResourcePathParams, ResourcePayload } from './resources';
|
||||
@@ -12,29 +14,37 @@ export interface Params<R extends ResourceName, E = unknown, D = ResourcePayload
|
||||
fetchParams?: Pick<FetchParams, 'body' | 'method' | 'headers'>;
|
||||
queryOptions?: Partial<Omit<UseQueryOptions<ResourcePayload<R>, ResourceError<E>, D>, 'queryFn'>>;
|
||||
logError?: boolean;
|
||||
chainSlug?: string;
|
||||
}
|
||||
|
||||
export function getResourceKey<R extends ResourceName>(resource: R, { pathParams, queryParams }: Params<R> = {}) {
|
||||
export interface GetResourceKeyParams<R extends ResourceName, E = unknown, D = ResourcePayload<R>>
|
||||
extends Pick<Params<R, E, D>, 'pathParams' | 'queryParams'> {
|
||||
chainSlug?: string;
|
||||
}
|
||||
|
||||
export function getResourceKey<R extends ResourceName>(resource: R, { pathParams, queryParams, chainSlug }: GetResourceKeyParams<R> = {}) {
|
||||
if (pathParams || queryParams) {
|
||||
return [ resource, { ...pathParams, ...queryParams } ];
|
||||
return [ resource, chainSlug, { ...pathParams, ...queryParams } ].filter(Boolean);
|
||||
}
|
||||
|
||||
return [ resource ];
|
||||
return [ resource, chainSlug ].filter(Boolean);
|
||||
}
|
||||
|
||||
export default function useApiQuery<R extends ResourceName, E = unknown, D = ResourcePayload<R>>(
|
||||
resource: R,
|
||||
{ queryOptions, pathParams, queryParams, fetchParams, logError }: Params<R, E, D> = {},
|
||||
{ queryOptions, pathParams, queryParams, fetchParams, logError, chainSlug }: Params<R, E, D> = {},
|
||||
) {
|
||||
const apiFetch = useApiFetch();
|
||||
const { chain } = useMultichainContext() ||
|
||||
{ chain: chainSlug ? multichainConfig()?.chains.find((chain) => chain.slug === chainSlug) : undefined };
|
||||
|
||||
return useQuery<ResourcePayload<R>, ResourceError<E>, D>({
|
||||
queryKey: queryOptions?.queryKey || getResourceKey(resource, { pathParams, queryParams }),
|
||||
queryKey: queryOptions?.queryKey || getResourceKey(resource, { pathParams, queryParams, chainSlug: chain?.slug }),
|
||||
queryFn: async({ signal }) => {
|
||||
// all errors and error typing is handled by react-query
|
||||
// so error response will never go to the data
|
||||
// that's why we are safe here to do type conversion "as Promise<ResourcePayload<R>>"
|
||||
return apiFetch(resource, { pathParams, queryParams, logError, fetchParams: { ...fetchParams, signal } }) as Promise<ResourcePayload<R>>;
|
||||
return apiFetch(resource, { pathParams, queryParams, chain, logError, fetchParams: { ...fetchParams, signal } }) as Promise<ResourcePayload<R>>;
|
||||
},
|
||||
...queryOptions,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
import type { ChainConfig } from 'types/multichain';
|
||||
|
||||
import multichainConfig from 'configs/multichain';
|
||||
import getQueryParamString from 'lib/router/getQueryParamString';
|
||||
|
||||
interface MultichainProviderProps {
|
||||
children: React.ReactNode;
|
||||
chainSlug?: string;
|
||||
}
|
||||
|
||||
export interface TMultichainContext {
|
||||
chain: ChainConfig;
|
||||
}
|
||||
|
||||
export const MultichainContext = React.createContext<TMultichainContext | null>(null);
|
||||
|
||||
export function MultichainProvider({ children, chainSlug: chainSlugProp }: MultichainProviderProps) {
|
||||
const router = useRouter();
|
||||
const chainSlugQueryParam = router.pathname.includes('chain-slug') ? getQueryParamString(router.query['chain-slug']) : undefined;
|
||||
|
||||
const [ chainSlug, setChainSlug ] = React.useState<string | undefined>(chainSlugProp ?? chainSlugQueryParam);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (chainSlugProp) {
|
||||
setChainSlug(chainSlugProp);
|
||||
}
|
||||
}, [ chainSlugProp ]);
|
||||
|
||||
const chain = React.useMemo(() => {
|
||||
const config = multichainConfig();
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!chainSlug) {
|
||||
return;
|
||||
}
|
||||
|
||||
return config.chains.find((chain) => chain.slug === chainSlug);
|
||||
}, [ chainSlug ]);
|
||||
|
||||
const value = React.useMemo(() => {
|
||||
if (!chain) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
chain,
|
||||
};
|
||||
}, [ chain ]);
|
||||
|
||||
return (
|
||||
<MultichainContext.Provider value={ value }>
|
||||
{ children }
|
||||
</MultichainContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useMultichainContext(disabled: boolean = !multichainConfig) {
|
||||
const context = React.useContext(MultichainContext);
|
||||
if (context === undefined || disabled) {
|
||||
return null;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@@ -54,6 +54,9 @@ export default function useFetch() {
|
||||
const error = {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
rateLimits: {
|
||||
bypassOptions: response.headers.get('bypass-429-option'),
|
||||
},
|
||||
};
|
||||
|
||||
if (meta?.logError && rollbar) {
|
||||
@@ -67,18 +70,16 @@ export default function useFetch() {
|
||||
if (!isJson) {
|
||||
return response.text().then(
|
||||
(textError) => Promise.reject({
|
||||
...error,
|
||||
payload: textError,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return response.json().then(
|
||||
(jsonError) => Promise.reject({
|
||||
...error,
|
||||
payload: jsonError as Error,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
}),
|
||||
() => {
|
||||
return Promise.reject(error);
|
||||
|
||||
@@ -118,6 +118,12 @@ export default function useNavItems(): ReturnType {
|
||||
icon: 'MUD_menu',
|
||||
isActive: pathname === '/mud-worlds',
|
||||
} : null;
|
||||
const epochs = config.features.celo.isEnabled ? {
|
||||
text: 'Epochs',
|
||||
nextRoute: { pathname: '/epochs' as const },
|
||||
icon: 'hourglass',
|
||||
isActive: pathname.startsWith('/epochs'),
|
||||
} : null;
|
||||
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
@@ -196,6 +202,7 @@ export default function useNavItems(): ReturnType {
|
||||
internalTxs,
|
||||
userOps,
|
||||
blocks,
|
||||
epochs,
|
||||
topAccounts,
|
||||
validators,
|
||||
verifiedContracts,
|
||||
|
||||
@@ -76,6 +76,8 @@ export default function useTimeAgoIncrement(ts: string | number | null, isEnable
|
||||
timeouts.push(endTimeoutId);
|
||||
};
|
||||
|
||||
setValue(dayjs(ts).fromNow());
|
||||
|
||||
isEnabled && startIncrement();
|
||||
|
||||
!isEnabled && setValue(dayjs(ts).fromNow());
|
||||
|
||||
@@ -54,6 +54,8 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
|
||||
'/name-domains/[name]': 'Regular page',
|
||||
'/validators': 'Root page',
|
||||
'/validators/[id]': 'Regular page',
|
||||
'/epochs': 'Root page',
|
||||
'/epochs/[number]': 'Regular page',
|
||||
'/gas-tracker': 'Root page',
|
||||
'/mud-worlds': 'Root page',
|
||||
'/token-transfers': 'Root page',
|
||||
@@ -61,6 +63,10 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
|
||||
'/pools': 'Root page',
|
||||
'/pools/[hash]': 'Regular page',
|
||||
'/interop-messages': 'Root page',
|
||||
'/chain/[chain-slug]/accounts/label/[slug]': 'Root page',
|
||||
'/chain/[chain-slug]/address/[hash]': 'Regular page',
|
||||
'/chain/[chain-slug]/block/[height_or_hash]': 'Regular page',
|
||||
'/chain/[chain-slug]/tx/[hash]': 'Regular page',
|
||||
'/operations': 'Root page',
|
||||
'/operation/[id]': 'Regular page',
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
|
||||
'/name-domains/[name]': DEFAULT_TEMPLATE,
|
||||
'/validators': DEFAULT_TEMPLATE,
|
||||
'/validators/[id]': DEFAULT_TEMPLATE,
|
||||
'/epochs': DEFAULT_TEMPLATE,
|
||||
'/epochs/[number]': DEFAULT_TEMPLATE,
|
||||
'/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,
|
||||
@@ -64,6 +66,10 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
|
||||
'/pools': DEFAULT_TEMPLATE,
|
||||
'/pools/[hash]': DEFAULT_TEMPLATE,
|
||||
'/interop-messages': DEFAULT_TEMPLATE,
|
||||
'/chain/[chain-slug]/accounts/label/[slug]': DEFAULT_TEMPLATE,
|
||||
'/chain/[chain-slug]/address/[hash]': DEFAULT_TEMPLATE,
|
||||
'/chain/[chain-slug]/block/[height_or_hash]': DEFAULT_TEMPLATE,
|
||||
'/chain/[chain-slug]/tx/[hash]': DEFAULT_TEMPLATE,
|
||||
'/operations': DEFAULT_TEMPLATE,
|
||||
'/operation/[id]': DEFAULT_TEMPLATE,
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
|
||||
'/name-domains/[name]': '%network_name% %name% domain details',
|
||||
'/validators': '%network_name% validators list',
|
||||
'/validators/[id]': '%network_name% validator %id% details',
|
||||
'/epochs': '%network_name% epochs',
|
||||
'/epochs/[number]': '%network_name% epoch %number% details',
|
||||
'/gas-tracker': 'Track %network_name% gas fees in %network_gwei%',
|
||||
'/mud-worlds': '%network_name% MUD worlds list',
|
||||
'/token-transfers': '%network_name% token transfers',
|
||||
@@ -61,6 +63,10 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
|
||||
'/pools': '%network_name% DEX pools',
|
||||
'/pools/[hash]': '%network_name% pool details',
|
||||
'/interop-messages': '%network_name% interop messages',
|
||||
'/chain/[chain-slug]/accounts/label/[slug]': '%network_name% addresses search by label',
|
||||
'/chain/[chain-slug]/address/[hash]': '%network_name% address details for %hash%',
|
||||
'/chain/[chain-slug]/block/[height_or_hash]': '%network_name% block %height_or_hash% details',
|
||||
'/chain/[chain-slug]/tx/[hash]': '%network_name% transaction %hash% details',
|
||||
'/operations': '%network_name% operations',
|
||||
'/operation/[id]': '%network_name% operation %id%',
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
|
||||
'/name-domains/[name]': 'Domain details',
|
||||
'/validators': 'Validators list',
|
||||
'/validators/[id]': 'Validator details',
|
||||
'/epochs': 'Epochs',
|
||||
'/epochs/[number]': 'Epoch details',
|
||||
'/gas-tracker': 'Gas tracker',
|
||||
'/mud-worlds': 'MUD worlds',
|
||||
'/token-transfers': 'Token transfers',
|
||||
@@ -59,6 +61,10 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
|
||||
'/pools': 'DEX pools',
|
||||
'/pools/[hash]': 'Pool details',
|
||||
'/interop-messages': 'Interop messages',
|
||||
'/chain/[chain-slug]/accounts/label/[slug]': 'Chain addresses search by label',
|
||||
'/chain/[chain-slug]/address/[hash]': 'Chain address details',
|
||||
'/chain/[chain-slug]/block/[height_or_hash]': 'Chain block details',
|
||||
'/chain/[chain-slug]/tx/[hash]': 'Chain transaction details',
|
||||
'/operations': 'Operations',
|
||||
'/operation/[id]': 'Operation details',
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ export default function useMixpanelInit() {
|
||||
|
||||
const mixpanelConfig: Partial<Config> = {
|
||||
debug: Boolean(debugFlagQuery.current || debugFlagCookie),
|
||||
persistence: 'localStorage',
|
||||
};
|
||||
const isAuth = Boolean(cookies.get(cookies.NAMES.API_TOKEN));
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ export enum EventTypes {
|
||||
BUTTON_CLICK = 'Button click',
|
||||
PROMO_BANNER = 'Promo banner',
|
||||
APP_FEEDBACK = 'App feedback',
|
||||
ADDRESS_WIDGET = 'Address widget',
|
||||
}
|
||||
|
||||
/* eslint-disable @stylistic/indent */
|
||||
@@ -169,5 +170,8 @@ Type extends EventTypes.APP_FEEDBACK ? {
|
||||
AppId: string;
|
||||
Score: number;
|
||||
} :
|
||||
Type extends EventTypes.ADDRESS_WIDGET ? {
|
||||
Name: string;
|
||||
} :
|
||||
undefined;
|
||||
/* eslint-enable @stylistic/indent */
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
import getQueryParamString from './getQueryParamString';
|
||||
|
||||
export default function useEtherscanRedirects() {
|
||||
const router = useRouter();
|
||||
|
||||
// The browser does not send the segment hash (or anchor) to the server,
|
||||
// so we have to handle such redirects for the etherscan-like links on the client side.
|
||||
React.useEffect(() => {
|
||||
const segmentHash = window.location.hash;
|
||||
|
||||
if (segmentHash) {
|
||||
switch (router.route) {
|
||||
case '/tx/[hash]': {
|
||||
const hash = getQueryParamString(router.query.hash);
|
||||
|
||||
switch (segmentHash) {
|
||||
case '#statechange':
|
||||
router.replace({
|
||||
pathname: '/tx/[hash]',
|
||||
query: { hash, tab: 'state' },
|
||||
});
|
||||
break;
|
||||
case '#eventlog':
|
||||
router.replace({
|
||||
pathname: '/tx/[hash]',
|
||||
query: { hash, tab: 'logs' },
|
||||
});
|
||||
break;
|
||||
case '#aa':
|
||||
router.replace({
|
||||
pathname: '/tx/[hash]',
|
||||
query: { hash, tab: 'user_ops' },
|
||||
});
|
||||
break;
|
||||
case '#internal':
|
||||
router.replace({
|
||||
pathname: '/tx/[hash]',
|
||||
query: { hash, tab: 'internal' },
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case '/address/[hash]': {
|
||||
const hash = getQueryParamString(router.query.hash);
|
||||
|
||||
switch (segmentHash) {
|
||||
case '#internaltx':
|
||||
router.replace({
|
||||
pathname: '/address/[hash]',
|
||||
query: { hash, tab: 'internal_txns' },
|
||||
});
|
||||
break;
|
||||
case '#tokentxns':
|
||||
router.replace({
|
||||
pathname: '/address/[hash]',
|
||||
query: { hash, tab: 'token_transfers' },
|
||||
});
|
||||
break;
|
||||
case '#asset-tokens':
|
||||
router.replace({
|
||||
pathname: '/address/[hash]',
|
||||
query: { hash, tab: 'tokens' },
|
||||
});
|
||||
break;
|
||||
case '#asset-nfts':
|
||||
router.replace({
|
||||
pathname: '/address/[hash]',
|
||||
query: { hash, tab: 'tokens_nfts' },
|
||||
});
|
||||
break;
|
||||
case '#aatx':
|
||||
router.replace({
|
||||
pathname: '/address/[hash]',
|
||||
query: { hash, tab: 'user_ops' },
|
||||
});
|
||||
break;
|
||||
case '#code':
|
||||
router.replace({
|
||||
pathname: '/address/[hash]',
|
||||
query: { hash, tab: 'contract' },
|
||||
});
|
||||
break;
|
||||
case '#readContract':
|
||||
router.replace({
|
||||
pathname: '/address/[hash]',
|
||||
query: { hash, tab: 'read_contract' },
|
||||
});
|
||||
break;
|
||||
case '#writeContract':
|
||||
router.replace({
|
||||
pathname: '/address/[hash]',
|
||||
query: { hash, tab: 'write_contract' },
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case '/token/[hash]': {
|
||||
const hash = getQueryParamString(router.query.hash);
|
||||
|
||||
switch (segmentHash) {
|
||||
case '#balances':
|
||||
router.replace({
|
||||
pathname: '/token/[hash]',
|
||||
query: { hash, tab: 'holders' },
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case '/stats': {
|
||||
switch (segmentHash) {
|
||||
case '#section-contracts-data':
|
||||
router.replace({
|
||||
pathname: '/stats',
|
||||
hash: 'contracts',
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// run only on mount
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [ ]);
|
||||
}
|
||||
@@ -7,5 +7,7 @@ export default function shortenString(string: string | null, charNumber: number
|
||||
return string;
|
||||
}
|
||||
|
||||
return string.slice(0, charNumber - 4) + '...' + string.slice(-4);
|
||||
const tailLength = charNumber < 8 ? 2 : 4;
|
||||
|
||||
return string.slice(0, charNumber - tailLength) + '...' + string.slice(-tailLength);
|
||||
}
|
||||
|
||||
+14
-3
@@ -1,9 +1,14 @@
|
||||
// https://hexdocs.pm/phoenix/js/
|
||||
import type { SocketConnectOption } from 'phoenix';
|
||||
import type { Channel, SocketConnectOption } from 'phoenix';
|
||||
import { Socket } from 'phoenix';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
export const SocketContext = React.createContext<Socket | null>(null);
|
||||
type ChannelRegistry = Record<string, { channel: Channel; subscribers: number }>;
|
||||
|
||||
export const SocketContext = React.createContext<{
|
||||
socket: Socket | null;
|
||||
channelRegistry: React.MutableRefObject<ChannelRegistry>;
|
||||
} | null>(null);
|
||||
|
||||
interface SocketProviderProps {
|
||||
children: React.ReactNode;
|
||||
@@ -13,6 +18,7 @@ interface SocketProviderProps {
|
||||
|
||||
export function SocketProvider({ children, options, url }: SocketProviderProps) {
|
||||
const [ socket, setSocket ] = useState<Socket | null>(null);
|
||||
const channelRegistry = React.useRef<ChannelRegistry>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (!url) {
|
||||
@@ -29,8 +35,13 @@ export function SocketProvider({ children, options, url }: SocketProviderProps)
|
||||
};
|
||||
}, [ options, url ]);
|
||||
|
||||
const value = React.useMemo(() => ({
|
||||
socket,
|
||||
channelRegistry,
|
||||
}), [ socket, channelRegistry ]);
|
||||
|
||||
return (
|
||||
<SocketContext.Provider value={ socket }>
|
||||
<SocketContext.Provider value={ value }>
|
||||
{ children }
|
||||
</SocketContext.Provider>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Channel } from 'phoenix';
|
||||
|
||||
import type * as multichain from '@blockscout/multichain-aggregator-types';
|
||||
import type { AddressCoinBalanceHistoryItem, AddressTokensBalancesSocketMessage } from 'types/api/address';
|
||||
import type { NewArbitrumBatchSocketResponse } from 'types/api/arbitrumL2';
|
||||
import type { NewBlockSocketResponse } from 'types/api/block';
|
||||
@@ -11,11 +12,13 @@ import type { Transaction } from 'types/api/transaction';
|
||||
import type { NewZkEvmBatchSocketResponse } from 'types/api/zkEvmL2';
|
||||
|
||||
export type SocketMessageParams = SocketMessage.NewBlock |
|
||||
SocketMessage.NewBlockMultichain |
|
||||
SocketMessage.BlocksIndexStatus |
|
||||
SocketMessage.InternalTxsIndexStatus |
|
||||
SocketMessage.TxStatusUpdate |
|
||||
SocketMessage.TxRawTrace |
|
||||
SocketMessage.NewTx |
|
||||
SocketMessage.NewInteropMessage |
|
||||
SocketMessage.NewPendingTx |
|
||||
SocketMessage.NewOptimisticDeposits |
|
||||
SocketMessage.NewArbitrumDeposits |
|
||||
@@ -49,11 +52,13 @@ interface SocketMessageParamsGeneric<Event extends string | undefined, Payload e
|
||||
|
||||
export namespace SocketMessage {
|
||||
export type NewBlock = SocketMessageParamsGeneric<'new_block', NewBlockSocketResponse>;
|
||||
export type NewBlockMultichain = SocketMessageParamsGeneric<'new_blocks', Array<{ block_number: number; chain_id: number }>>;
|
||||
export type BlocksIndexStatus = SocketMessageParamsGeneric<'index_status', { finished: boolean; ratio: string }>;
|
||||
export type InternalTxsIndexStatus = SocketMessageParamsGeneric<'index_status', { finished: boolean; ratio: string }>;
|
||||
export type TxStatusUpdate = SocketMessageParamsGeneric<'collated', NewBlockSocketResponse>;
|
||||
export type TxRawTrace = SocketMessageParamsGeneric<'raw_trace', RawTracesResponse>;
|
||||
export type NewTx = SocketMessageParamsGeneric<'transaction', { transaction: number }>;
|
||||
export type NewInteropMessage = SocketMessageParamsGeneric<'new_messages', Array<multichain.InteropMessage>>;
|
||||
export type NewPendingTx = SocketMessageParamsGeneric<'pending_transaction', { pending_transaction: number }>;
|
||||
export type NewOptimisticDeposits = SocketMessageParamsGeneric<'new_optimism_deposits', { deposits: number }>;
|
||||
export type NewArbitrumDeposits = SocketMessageParamsGeneric<'new_messages_to_rollup_amount', { new_messages_to_rollup_amount: number }>;
|
||||
|
||||
@@ -3,8 +3,6 @@ import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { useSocket } from './context';
|
||||
|
||||
const CHANNEL_REGISTRY: Record<string, { channel: Channel; subscribers: number }> = {};
|
||||
|
||||
interface Params {
|
||||
topic: string | undefined;
|
||||
params?: object;
|
||||
@@ -15,7 +13,7 @@ interface Params {
|
||||
}
|
||||
|
||||
export default function useSocketChannel({ topic, params, isDisabled, onJoin, onSocketClose, onSocketError }: Params) {
|
||||
const socket = useSocket();
|
||||
const { socket, channelRegistry } = useSocket() || {};
|
||||
const [ channel, setChannel ] = useState<Channel>();
|
||||
const onCloseRef = useRef<string>(undefined);
|
||||
const onErrorRef = useRef<string>(undefined);
|
||||
@@ -47,18 +45,18 @@ export default function useSocketChannel({ topic, params, isDisabled, onJoin, on
|
||||
}, [ channel, isDisabled ]);
|
||||
|
||||
useEffect(() => {
|
||||
if (socket === null || isDisabled || !topic) {
|
||||
if (!socket || isDisabled || !topic || !channelRegistry) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ch: Channel;
|
||||
if (CHANNEL_REGISTRY[topic]) {
|
||||
ch = CHANNEL_REGISTRY[topic].channel;
|
||||
CHANNEL_REGISTRY[topic].subscribers++;
|
||||
if (channelRegistry.current[topic]) {
|
||||
ch = channelRegistry.current[topic].channel;
|
||||
channelRegistry.current[topic].subscribers++;
|
||||
onJoinRef.current?.(ch, '');
|
||||
} else {
|
||||
ch = socket.channel(topic);
|
||||
CHANNEL_REGISTRY[topic] = { channel: ch, subscribers: 1 };
|
||||
channelRegistry.current[topic] = { channel: ch, subscribers: 1 };
|
||||
ch.join()
|
||||
.receive('ok', (message) => onJoinRef.current?.(ch, message))
|
||||
.receive('error', () => {
|
||||
@@ -68,18 +66,20 @@ export default function useSocketChannel({ topic, params, isDisabled, onJoin, on
|
||||
|
||||
setChannel(ch);
|
||||
|
||||
const currentRegistry = channelRegistry.current;
|
||||
|
||||
return () => {
|
||||
if (CHANNEL_REGISTRY[topic]) {
|
||||
CHANNEL_REGISTRY[topic].subscribers > 0 && CHANNEL_REGISTRY[topic].subscribers--;
|
||||
if (CHANNEL_REGISTRY[topic].subscribers === 0) {
|
||||
if (currentRegistry[topic]) {
|
||||
currentRegistry[topic].subscribers > 0 && currentRegistry[topic].subscribers--;
|
||||
if (currentRegistry[topic].subscribers === 0) {
|
||||
ch.leave();
|
||||
delete CHANNEL_REGISTRY[topic];
|
||||
delete currentRegistry[topic];
|
||||
}
|
||||
}
|
||||
|
||||
setChannel(undefined);
|
||||
};
|
||||
}, [ socket, topic, params, isDisabled, onSocketError ]);
|
||||
}, [ socket, topic, params, isDisabled, onSocketError, channelRegistry ]);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
+35
-20
@@ -1,31 +1,36 @@
|
||||
import { type Chain } from 'viem';
|
||||
|
||||
import config from 'configs/app';
|
||||
import appConfig from 'configs/app';
|
||||
import multichainConfig from 'configs/multichain';
|
||||
|
||||
export const currentChain: Chain = {
|
||||
id: Number(config.chain.id),
|
||||
name: config.chain.name ?? '',
|
||||
nativeCurrency: {
|
||||
decimals: config.chain.currency.decimals,
|
||||
name: config.chain.currency.name ?? '',
|
||||
symbol: config.chain.currency.symbol ?? '',
|
||||
},
|
||||
rpcUrls: {
|
||||
'default': {
|
||||
http: config.chain.rpcUrls,
|
||||
const getChainInfo = (config: typeof appConfig = appConfig) => {
|
||||
return {
|
||||
id: Number(config.chain.id),
|
||||
name: config.chain.name ?? '',
|
||||
nativeCurrency: {
|
||||
decimals: config.chain.currency.decimals,
|
||||
name: config.chain.currency.name ?? '',
|
||||
symbol: config.chain.currency.symbol ?? '',
|
||||
},
|
||||
},
|
||||
blockExplorers: {
|
||||
'default': {
|
||||
name: 'Blockscout',
|
||||
url: config.app.baseUrl,
|
||||
rpcUrls: {
|
||||
'default': {
|
||||
http: config.chain.rpcUrls,
|
||||
},
|
||||
},
|
||||
},
|
||||
testnet: config.chain.isTestnet,
|
||||
blockExplorers: {
|
||||
'default': {
|
||||
name: 'Blockscout',
|
||||
url: config.app.baseUrl,
|
||||
},
|
||||
},
|
||||
testnet: config.chain.isTestnet,
|
||||
};
|
||||
};
|
||||
|
||||
export const currentChain: Chain | undefined = !appConfig.features.opSuperchain.isEnabled ? getChainInfo() : undefined;
|
||||
|
||||
export const parentChain: Chain | undefined = (() => {
|
||||
const rollupFeature = config.features.rollup;
|
||||
const rollupFeature = appConfig.features.rollup;
|
||||
|
||||
const parentChain = rollupFeature.isEnabled && rollupFeature.parentChain;
|
||||
|
||||
@@ -55,3 +60,13 @@ export const parentChain: Chain | undefined = (() => {
|
||||
testnet: parentChain.isTestnet,
|
||||
};
|
||||
})();
|
||||
|
||||
export const clusterChains: Array<Chain> | undefined = (() => {
|
||||
const config = multichainConfig();
|
||||
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
|
||||
return config.chains.map(({ config }) => getChainInfo(config)).filter(Boolean);
|
||||
})();
|
||||
|
||||
+2
-1
@@ -3,7 +3,8 @@ import { createPublicClient, http } from 'viem';
|
||||
import { currentChain } from './chains';
|
||||
|
||||
export const publicClient = (() => {
|
||||
if (currentChain.rpcUrls.default.http.filter(Boolean).length === 0) {
|
||||
// TODO @tom2drum public clients for multichain (currently used only in degradation views)
|
||||
if (currentChain?.rpcUrls.default.http.filter(Boolean).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+42
-11
@@ -1,15 +1,48 @@
|
||||
import { WagmiAdapter } from '@reown/appkit-adapter-wagmi';
|
||||
import type { AppKitNetwork } from '@reown/appkit/networks';
|
||||
import type { Chain } from 'viem';
|
||||
import type { Chain, Transport } from 'viem';
|
||||
import { fallback, http } from 'viem';
|
||||
import { createConfig } from 'wagmi';
|
||||
|
||||
import config from 'configs/app';
|
||||
import { currentChain, parentChain } from 'lib/web3/chains';
|
||||
import appConfig from 'configs/app';
|
||||
import multichainConfig from 'configs/multichain';
|
||||
import { currentChain, parentChain, clusterChains } from 'lib/web3/chains';
|
||||
|
||||
const feature = config.features.blockchainInteraction;
|
||||
const feature = appConfig.features.blockchainInteraction;
|
||||
|
||||
const chains = [ currentChain, parentChain ].filter(Boolean);
|
||||
const chains = [ currentChain, parentChain, ...(clusterChains ?? []) ].filter(Boolean);
|
||||
|
||||
const getChainTransportFromConfig = (config: typeof appConfig, readOnly?: boolean): Record<string, Transport> => {
|
||||
if (!config.chain.id) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
[config.chain.id]: fallback(
|
||||
config.chain.rpcUrls
|
||||
.concat(readOnly ? `${ config.apis.general.endpoint }/api/eth-rpc` : '')
|
||||
.filter(Boolean)
|
||||
.map((url) => http(url, { batch: { wait: 100 } })),
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
const reduceClusterChainsToTransportConfig = (readOnly: boolean): Record<string, Transport> => {
|
||||
const config = multichainConfig();
|
||||
|
||||
if (!config) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return config.chains
|
||||
.map(({ config }) => getChainTransportFromConfig(config, readOnly))
|
||||
.reduce((result, item) => {
|
||||
Object.entries(item).map(([ id, transport ]) => {
|
||||
result[id] = transport;
|
||||
});
|
||||
return result;
|
||||
}, {} as Record<string, Transport>);
|
||||
};
|
||||
|
||||
const wagmi = (() => {
|
||||
|
||||
@@ -17,12 +50,9 @@ const wagmi = (() => {
|
||||
const wagmiConfig = createConfig({
|
||||
chains: chains as [Chain, ...Array<Chain>],
|
||||
transports: {
|
||||
[currentChain.id]: fallback(
|
||||
config.chain.rpcUrls
|
||||
.map((url) => http(url))
|
||||
.concat(http(`${ config.apis.general.endpoint }/api/eth-rpc`)),
|
||||
),
|
||||
...getChainTransportFromConfig(appConfig, true),
|
||||
...(parentChain ? { [parentChain.id]: http(parentChain.rpcUrls.default.http[0]) } : {}),
|
||||
...reduceClusterChainsToTransportConfig(true),
|
||||
},
|
||||
ssr: true,
|
||||
batch: { multicall: { wait: 100 } },
|
||||
@@ -35,8 +65,9 @@ const wagmi = (() => {
|
||||
networks: chains as Array<AppKitNetwork>,
|
||||
multiInjectedProviderDiscovery: true,
|
||||
transports: {
|
||||
[currentChain.id]: fallback(config.chain.rpcUrls.map((url) => http(url))),
|
||||
...getChainTransportFromConfig(appConfig, false),
|
||||
...(parentChain ? { [parentChain.id]: http() } : {}),
|
||||
...reduceClusterChainsToTransportConfig(false),
|
||||
},
|
||||
projectId: feature.walletConnect.projectId,
|
||||
ssr: true,
|
||||
|
||||
+5
-5
@@ -1,12 +1,10 @@
|
||||
import type { NextRequest } from 'next/server';
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
import generateCspPolicy from 'nextjs/csp/generateCspPolicy';
|
||||
import * as csp from 'nextjs/csp/index';
|
||||
import * as middlewares from 'nextjs/middlewares/index';
|
||||
|
||||
const cspPolicy = generateCspPolicy();
|
||||
|
||||
export function middleware(req: NextRequest) {
|
||||
export async function middleware(req: NextRequest) {
|
||||
const isPageRequest = req.headers.get('accept')?.includes('text/html');
|
||||
const start = Date.now();
|
||||
|
||||
@@ -27,7 +25,9 @@ export function middleware(req: NextRequest) {
|
||||
|
||||
const end = Date.now();
|
||||
|
||||
res.headers.append('Content-Security-Policy', cspPolicy);
|
||||
const cspHeader = await csp.get();
|
||||
|
||||
res.headers.append('Content-Security-Policy', cspHeader);
|
||||
res.headers.append('Server-Timing', `middleware;dur=${ end - start }`);
|
||||
res.headers.append('Docker-ID', process.env.HOSTNAME || '');
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ export const token: Address = {
|
||||
coin_balance: '1',
|
||||
creation_transaction_hash: '0xc38cf7377bf72d6436f63c37b01b24d032101f20ec1849286dc703c712f10c98',
|
||||
creator_address_hash: '0x34A9c688512ebdB575e82C50c9803F6ba2916E72',
|
||||
creation_status: 'success',
|
||||
exchange_rate: '0.04311',
|
||||
has_logs: false,
|
||||
has_token_transfers: true,
|
||||
@@ -94,6 +95,7 @@ export const eoa: Address = {
|
||||
coin_balance: '2782650189688719421432220500',
|
||||
creation_transaction_hash: '0xf2aff6501b632604c39978b47d309813d8a1bcca721864bbe86abf59704f195e',
|
||||
creator_address_hash: '0x803ad3F50b9e1fF68615e8B053A186e1be288943',
|
||||
creation_status: null,
|
||||
exchange_rate: '0.04311',
|
||||
has_logs: true,
|
||||
has_token_transfers: false,
|
||||
@@ -117,6 +119,7 @@ export const contract: Address = {
|
||||
coin_balance: '27826501896887194214322205',
|
||||
creation_transaction_hash: '0xf2aff6501b632604c39978b47d309813d8a1bcca721864bbe86abf59704f195e',
|
||||
creator_address_hash: '0x803ad3F50b9e1fF68615e8B053A186e1be288943',
|
||||
creation_status: 'success',
|
||||
exchange_rate: '0.04311',
|
||||
has_logs: true,
|
||||
has_token_transfers: false,
|
||||
@@ -142,6 +145,7 @@ export const validator: Address = {
|
||||
coin_balance: '22910462800601256910890',
|
||||
creation_transaction_hash: null,
|
||||
creator_address_hash: null,
|
||||
creation_status: null,
|
||||
exchange_rate: '0.00432018',
|
||||
has_logs: false,
|
||||
has_token_transfers: false,
|
||||
|
||||
@@ -11,8 +11,6 @@ export const epochRewards: AddressEpochRewardsResponse = {
|
||||
amount: '136609473658452408568',
|
||||
account: withName,
|
||||
associated_account: withName,
|
||||
block_hash: '0x',
|
||||
block_number: 26369280,
|
||||
block_timestamp: '2022-05-15T13:16:24Z',
|
||||
epoch_number: 1526,
|
||||
token: tokenInfo,
|
||||
@@ -22,8 +20,6 @@ export const epochRewards: AddressEpochRewardsResponse = {
|
||||
amount: '117205842355246195095',
|
||||
account: withoutName,
|
||||
associated_account: withoutName,
|
||||
block_hash: '0x',
|
||||
block_number: 26352000,
|
||||
block_timestamp: '2022-05-15T13:16:24Z',
|
||||
epoch_number: 1525,
|
||||
token: tokenInfo,
|
||||
@@ -33,8 +29,6 @@ export const epochRewards: AddressEpochRewardsResponse = {
|
||||
amount: '125659647325556554060',
|
||||
account: withEns,
|
||||
associated_account: withEns,
|
||||
block_hash: '0x',
|
||||
block_number: 26300160,
|
||||
block_timestamp: '2022-05-15T13:16:24Z',
|
||||
epoch_number: 1524,
|
||||
token: tokenInfo,
|
||||
@@ -43,7 +37,7 @@ export const epochRewards: AddressEpochRewardsResponse = {
|
||||
next_page_params: {
|
||||
amount: '71952055594478242556',
|
||||
associated_account_address_hash: '0x30d060f129817c4de5fbc1366d53e19f43c8c64f',
|
||||
block_number: 25954560,
|
||||
epoch_number: 25954560,
|
||||
items_count: 50,
|
||||
type: 'delegated_payment',
|
||||
},
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
import type { Address3rdPartyWidget } from 'types/views/address';
|
||||
|
||||
export const widgets = [
|
||||
'widget-1',
|
||||
'widget-2',
|
||||
'widget-3',
|
||||
'widget-4',
|
||||
'widget-5',
|
||||
'widget-6',
|
||||
'widget-7',
|
||||
'widget-8',
|
||||
'widget-9',
|
||||
] as const;
|
||||
|
||||
export const values = [ 0, 2534783, 75.34, undefined, 1553.5, 100, 0.99, 333, undefined ];
|
||||
|
||||
export const config: Record<string, Address3rdPartyWidget> = {
|
||||
'widget-1': {
|
||||
name: 'Widget 1',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'Value',
|
||||
hint: 'Hint',
|
||||
valuePath: 'value',
|
||||
},
|
||||
'widget-2': {
|
||||
name: 'Widget 2',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'Another value',
|
||||
valuePath: 'value',
|
||||
},
|
||||
'widget-3': {
|
||||
name: 'Widget 3',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'One more value',
|
||||
hint: 'Hint',
|
||||
valuePath: 'value',
|
||||
},
|
||||
'widget-4': {
|
||||
name: 'Widget 4',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'Empty value',
|
||||
valuePath: 'another_value',
|
||||
},
|
||||
'widget-5': {
|
||||
name: 'Widget 5',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'Test value',
|
||||
hint: 'Hint',
|
||||
valuePath: 'value',
|
||||
},
|
||||
'widget-6': {
|
||||
name: 'Widget 6',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'Another test value',
|
||||
valuePath: 'value',
|
||||
},
|
||||
'widget-7': {
|
||||
name: 'Widget 7',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'One more test value',
|
||||
hint: 'Hint',
|
||||
valuePath: 'value',
|
||||
},
|
||||
'widget-8': {
|
||||
name: 'Widget 8',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'Final test value',
|
||||
valuePath: 'value',
|
||||
},
|
||||
'widget-9': {
|
||||
name: 'Widget 9',
|
||||
url: 'https://www.example.com',
|
||||
pages: [ 'eoa', 'contract', 'token' ],
|
||||
icon: 'http://localhost:3000/widget-logo.png',
|
||||
title: 'Another empty value',
|
||||
hint: 'Hint',
|
||||
valuePath: 'value',
|
||||
},
|
||||
};
|
||||
@@ -168,7 +168,7 @@ export const celo: Block = {
|
||||
recipient: addressMock.contract,
|
||||
},
|
||||
epoch_number: 1486,
|
||||
is_epoch_block: true,
|
||||
l1_era_finalized_epoch_number: 1485,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import { padStart } from 'es-toolkit/compat';
|
||||
|
||||
import type { BlockEpoch, BlockEpochElectionRewardDetails, BlockEpochElectionRewardDetailsResponse } from 'types/api/block';
|
||||
|
||||
import * as addressMock from '../address/address';
|
||||
import * as tokenMock from '../tokens/tokenInfo';
|
||||
import * as tokenTransferMock from '../tokens/tokenTransfer';
|
||||
|
||||
export const blockEpoch1: BlockEpoch = {
|
||||
number: 1486,
|
||||
distribution: {
|
||||
carbon_offsetting_transfer: tokenTransferMock.erc20,
|
||||
community_transfer: tokenTransferMock.erc20,
|
||||
reserve_bolster_transfer: null,
|
||||
},
|
||||
aggregated_election_rewards: {
|
||||
delegated_payment: {
|
||||
count: 0,
|
||||
total: '71210001063118670575',
|
||||
token: tokenMock.tokenInfoERC20d,
|
||||
},
|
||||
group: {
|
||||
count: 10,
|
||||
total: '157705500305820107521',
|
||||
token: tokenMock.tokenInfoERC20b,
|
||||
},
|
||||
validator: {
|
||||
count: 10,
|
||||
total: '1348139501689262297152',
|
||||
token: tokenMock.tokenInfoERC20c,
|
||||
},
|
||||
voter: {
|
||||
count: 38,
|
||||
total: '2244419545166303388',
|
||||
token: tokenMock.tokenInfoERC20a,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function getRewardDetailsItem(index: number): BlockEpochElectionRewardDetails {
|
||||
return {
|
||||
amount: `${ 100 - index }210001063118670575`,
|
||||
account: {
|
||||
...addressMock.withoutName,
|
||||
hash: `0x30D060F129817c4DE5fBc1366d53e19f43c8c6${ padStart(String(index), 2, '0') }`,
|
||||
},
|
||||
associated_account: {
|
||||
...addressMock.withoutName,
|
||||
hash: `0x456f41406B32c45D59E539e4BBA3D7898c3584${ padStart(String(index), 2, '0') }`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const electionRewardDetails1: BlockEpochElectionRewardDetailsResponse = {
|
||||
items: Array(15).fill('').map((item, index) => getRewardDetailsItem(index)),
|
||||
next_page_params: null,
|
||||
};
|
||||
@@ -79,6 +79,10 @@ export const FOOTER_LINKS: Array<CustomLinksGroup> = [
|
||||
{
|
||||
text: 'MetaDock',
|
||||
url: 'https://blocksec.com/metadock',
|
||||
iconUrl: [
|
||||
'http://localhost:3000/mocks/image_s.jpg',
|
||||
'http://localhost:3000/mocks/image_svg.svg',
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Sourcify',
|
||||
|
||||
@@ -7,6 +7,7 @@ export const verified: SmartContract = {
|
||||
compiler_version: 'v0.5.16+commit.9c3226ce',
|
||||
constructor_args: 'constructor_args',
|
||||
creation_bytecode: 'creation_bytecode',
|
||||
creation_status: 'success',
|
||||
deployed_bytecode: 'deployed_bytecode',
|
||||
compiler_settings: {
|
||||
evmVersion: 'london',
|
||||
@@ -33,7 +34,6 @@ export const verified: SmartContract = {
|
||||
],
|
||||
language: 'solidity',
|
||||
license_type: 'gnu_gpl_v3',
|
||||
is_self_destructed: false,
|
||||
is_verified_via_eth_bytecode_db: null,
|
||||
is_changed_bytecode: null,
|
||||
is_verified_via_sourcify: null,
|
||||
@@ -88,7 +88,7 @@ export const withProxyAddress: SmartContract = {
|
||||
|
||||
export const selfDestructed: SmartContract = {
|
||||
...verified,
|
||||
is_self_destructed: true,
|
||||
creation_status: 'selfdestructed',
|
||||
};
|
||||
|
||||
export const withChangedByteCode: SmartContract = {
|
||||
@@ -122,7 +122,7 @@ export const nonVerified: SmartContract = {
|
||||
is_blueprint: false,
|
||||
creation_bytecode: 'creation_bytecode',
|
||||
deployed_bytecode: 'deployed_bytecode',
|
||||
is_self_destructed: false,
|
||||
creation_status: 'success',
|
||||
abi: null,
|
||||
compiler_version: null,
|
||||
evm_version: null,
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
import { padStart } from 'es-toolkit/compat';
|
||||
|
||||
import type { CeloEpochDetails, CeloEpochElectionRewardDetails, CeloEpochElectionRewardDetailsResponse, CeloEpochListResponse } from 'types/api/epochs';
|
||||
|
||||
import * as addressMock from '../address/address';
|
||||
import * as tokenMock from '../tokens/tokenInfo';
|
||||
import * as tokenTransferMock from '../tokens/tokenTransfer';
|
||||
|
||||
export const epoch1: CeloEpochDetails = {
|
||||
number: 1739,
|
||||
is_finalized: true,
|
||||
type: 'L1',
|
||||
timestamp: '2022-06-10T01:27:52.000000Z',
|
||||
start_block_number: 48477132,
|
||||
start_processing_block_hash: '0x9dece1eb0e26a95fdf57d2f3a65a6f2e00ca0192e8e3dd157eca0cd323670fa1',
|
||||
start_processing_block_number: 48563546,
|
||||
end_processing_block_hash: '0x9dece1eb0e26a95fdf57d2f3a65a6f2e00ca0192e8e3dd157eca0cd323670fa2',
|
||||
end_processing_block_number: 48563552,
|
||||
end_block_number: 48563551,
|
||||
distribution: {
|
||||
carbon_offsetting_transfer: tokenTransferMock.erc20,
|
||||
community_transfer: tokenTransferMock.erc20,
|
||||
transfers_total: {
|
||||
token: tokenMock.tokenInfoERC20a,
|
||||
total: {
|
||||
value: '1000000000000000000',
|
||||
decimals: '18',
|
||||
},
|
||||
},
|
||||
},
|
||||
aggregated_election_rewards: {
|
||||
delegated_payment: {
|
||||
count: 0,
|
||||
total: '71210001063118670575',
|
||||
token: tokenMock.tokenInfoERC20d,
|
||||
},
|
||||
group: {
|
||||
count: 10,
|
||||
total: '157705500305820107521',
|
||||
token: tokenMock.tokenInfoERC20b,
|
||||
},
|
||||
validator: {
|
||||
count: 10,
|
||||
total: '1348139501689262297152',
|
||||
token: tokenMock.tokenInfoERC20c,
|
||||
},
|
||||
voter: {
|
||||
count: 38,
|
||||
total: '2244419545166303388',
|
||||
token: tokenMock.tokenInfoERC20a,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const epochUnfinalized: CeloEpochDetails = {
|
||||
number: 1740,
|
||||
is_finalized: false,
|
||||
type: 'L2',
|
||||
timestamp: null,
|
||||
start_block_number: 48477132,
|
||||
start_processing_block_hash: null,
|
||||
start_processing_block_number: null,
|
||||
end_processing_block_hash: null,
|
||||
end_processing_block_number: null,
|
||||
end_block_number: null,
|
||||
distribution: null,
|
||||
aggregated_election_rewards: null,
|
||||
};
|
||||
|
||||
export const list: CeloEpochListResponse = {
|
||||
items: [
|
||||
{
|
||||
timestamp: '2022-11-10T01:27:52.000000Z',
|
||||
number: 1739,
|
||||
type: 'L2',
|
||||
is_finalized: false,
|
||||
start_block_number: 48477132,
|
||||
end_block_number: null,
|
||||
distribution: null,
|
||||
},
|
||||
{
|
||||
timestamp: '2022-06-09T01:27:32.000000Z',
|
||||
number: 1738,
|
||||
type: 'L1',
|
||||
is_finalized: true,
|
||||
end_block_number: 18477131,
|
||||
start_block_number: 18390714,
|
||||
distribution: {
|
||||
carbon_offsetting_transfer: {
|
||||
decimals: '18',
|
||||
value: '1723199576750509130678',
|
||||
},
|
||||
community_transfer: {
|
||||
decimals: '18',
|
||||
value: '68927983070020365227',
|
||||
},
|
||||
transfers_total: {
|
||||
decimals: '18',
|
||||
value: '1792127559820529495905',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
next_page_params: null,
|
||||
};
|
||||
|
||||
function getRewardDetailsItem(index: number): CeloEpochElectionRewardDetails {
|
||||
return {
|
||||
amount: `${ 100 - index }210001063118670575`,
|
||||
account: {
|
||||
...addressMock.withoutName,
|
||||
hash: `0x30D060F129817c4DE5fBc1366d53e19f43c8c6${ padStart(String(index), 2, '0') }`,
|
||||
},
|
||||
associated_account: {
|
||||
...addressMock.withoutName,
|
||||
hash: `0x456f41406B32c45D59E539e4BBA3D7898c3584${ padStart(String(index), 2, '0') }`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const electionRewardDetails1: CeloEpochElectionRewardDetailsResponse = {
|
||||
items: Array(15).fill('').map((item, index) => getRewardDetailsItem(index)),
|
||||
next_page_params: null,
|
||||
};
|
||||
@@ -15,6 +15,7 @@ function generateCspPolicy() {
|
||||
descriptors.marketplace(),
|
||||
descriptors.mixpanel(),
|
||||
descriptors.monaco(),
|
||||
descriptors.multichain(),
|
||||
descriptors.rollbar(),
|
||||
descriptors.safe(),
|
||||
descriptors.usernameApi(),
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import appConfig from 'configs/app';
|
||||
import * as multichainConfig from 'configs/multichain/config.edge';
|
||||
|
||||
import generateCspPolicy from './generateCspPolicy';
|
||||
|
||||
let cspPolicy: string | undefined = undefined;
|
||||
|
||||
export async function get() {
|
||||
if (!cspPolicy) {
|
||||
appConfig.features.opSuperchain.isEnabled && await multichainConfig.load();
|
||||
cspPolicy = generateCspPolicy();
|
||||
}
|
||||
|
||||
return cspPolicy;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ export function app(): CspDev.DirectiveDescriptor {
|
||||
|
||||
// APIs
|
||||
...Object.values(config.apis).filter(Boolean).map((api) => api.endpoint),
|
||||
config.apis.general.socketEndpoint,
|
||||
...Object.values(config.apis).filter(Boolean).map((api) => api.socketEndpoint),
|
||||
|
||||
// chain RPC server
|
||||
...config.chain.rpcUrls,
|
||||
|
||||
@@ -10,6 +10,7 @@ export { helia } from './helia';
|
||||
export { marketplace } from './marketplace';
|
||||
export { mixpanel } from './mixpanel';
|
||||
export { monaco } from './monaco';
|
||||
export { multichain } from './multichain';
|
||||
export { rollbar } from './rollbar';
|
||||
export { safe } from './safe';
|
||||
export { usernameApi } from './usernameApi';
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import type CspDev from 'csp-dev';
|
||||
|
||||
import * as multichainConfig from 'configs/multichain/config.edge';
|
||||
|
||||
export function multichain(): CspDev.DirectiveDescriptor {
|
||||
const value = multichainConfig.getValue();
|
||||
if (!value) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const apiEndpoints = value.chains.map((chain) => {
|
||||
return [
|
||||
...Object.values(chain.config.apis).filter(Boolean).map((api) => api.endpoint),
|
||||
...Object.values(chain.config.apis).filter(Boolean).map((api) => api.socketEndpoint),
|
||||
].filter(Boolean);
|
||||
}).flat();
|
||||
|
||||
const rpcEndpoints = value.chains.map(({ config }) => config.chain.rpcUrls).flat();
|
||||
|
||||
return {
|
||||
'connect-src': [
|
||||
...apiEndpoints,
|
||||
...rpcEndpoints,
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -6,12 +6,14 @@ import type { RollupType } from 'types/client/rollup';
|
||||
import type { Route } from 'nextjs-routes';
|
||||
|
||||
import config from 'configs/app';
|
||||
const rollupFeature = config.features.rollup;
|
||||
const adBannerFeature = config.features.adsBanner;
|
||||
import multichainConfig from 'configs/multichain';
|
||||
import isNeedProxy from 'lib/api/isNeedProxy';
|
||||
import * as cookies from 'lib/cookies';
|
||||
import type * as metadata from 'lib/metadata';
|
||||
|
||||
const rollupFeature = config.features.rollup;
|
||||
const adBannerFeature = config.features.adsBanner;
|
||||
|
||||
export interface Props<Pathname extends Route['pathname'] = never> {
|
||||
query: Route['query'];
|
||||
cookies: string;
|
||||
@@ -390,6 +392,16 @@ export const tac: GetServerSideProps<Props> = async(context) => {
|
||||
return base(context);
|
||||
};
|
||||
|
||||
export const celo: GetServerSideProps<Props> = async(context) => {
|
||||
if (!config.features.celo.isEnabled) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
}
|
||||
|
||||
return base(context);
|
||||
};
|
||||
|
||||
export const interopMessages: GetServerSideProps<Props> = async(context) => {
|
||||
const rollupFeature = config.features.rollup;
|
||||
if (!rollupFeature.isEnabled || !rollupFeature.interopEnabled) {
|
||||
@@ -401,6 +413,29 @@ export const interopMessages: GetServerSideProps<Props> = async(context) => {
|
||||
return base(context);
|
||||
};
|
||||
|
||||
export const opSuperchain: GetServerSideProps<Props> = async(context) => {
|
||||
if (!config.features.opSuperchain.isEnabled) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
}
|
||||
|
||||
return base(context);
|
||||
};
|
||||
|
||||
export const opSuperchainAccountsLabelSearch: GetServerSideProps<Props> = async(context) => {
|
||||
const chainSlug = context.params?.['chain-slug'];
|
||||
const chain = multichainConfig()?.chains.find((chain) => chain.slug === chainSlug);
|
||||
|
||||
if (!chain?.config.features.addressMetadata.isEnabled || !context.query.tagType) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
}
|
||||
|
||||
return opSuperchain(context);
|
||||
};
|
||||
|
||||
export const pools: GetServerSideProps<Props> = async(context) => {
|
||||
if (!config.features.pools.isEnabled) {
|
||||
return {
|
||||
|
||||
Vendored
+6
@@ -38,11 +38,17 @@ declare module "nextjs-routes" {
|
||||
| DynamicRoute<"/block/countdown/[height]", { "height": string }>
|
||||
| StaticRoute<"/block/countdown">
|
||||
| StaticRoute<"/blocks">
|
||||
| DynamicRoute<"/chain/[chain-slug]/accounts/label/[slug]", { "chain-slug": string; "slug": string }>
|
||||
| DynamicRoute<"/chain/[chain-slug]/address/[hash]", { "chain-slug": string; "hash": string }>
|
||||
| DynamicRoute<"/chain/[chain-slug]/block/[height_or_hash]", { "chain-slug": string; "height_or_hash": string }>
|
||||
| DynamicRoute<"/chain/[chain-slug]/tx/[hash]", { "chain-slug": string; "hash": string }>
|
||||
| StaticRoute<"/chakra">
|
||||
| StaticRoute<"/contract-verification">
|
||||
| StaticRoute<"/csv-export">
|
||||
| StaticRoute<"/deposits">
|
||||
| StaticRoute<"/dispute-games">
|
||||
| DynamicRoute<"/epochs/[number]", { "number": string }>
|
||||
| StaticRoute<"/epochs">
|
||||
| StaticRoute<"/gas-tracker">
|
||||
| StaticRoute<"/graphiql">
|
||||
| StaticRoute<"/">
|
||||
|
||||
+79
-2
@@ -1,4 +1,4 @@
|
||||
const oldUrls = [
|
||||
const OLD_UI_URLS = [
|
||||
// ACCOUNT
|
||||
{
|
||||
source: '/account/tag_address',
|
||||
@@ -266,9 +266,86 @@ const oldUrls = [
|
||||
},
|
||||
];
|
||||
|
||||
const ETHERSCAN_URLS = [
|
||||
{
|
||||
source: '/txsAA',
|
||||
destination: '/ops',
|
||||
},
|
||||
{
|
||||
source: '/txs',
|
||||
has: [
|
||||
{ type: 'query', key: 'block' },
|
||||
],
|
||||
destination: '/block/:block?tab=txs',
|
||||
},
|
||||
{
|
||||
source: '/txsInternal',
|
||||
has: [
|
||||
{ type: 'query', key: 'block' },
|
||||
],
|
||||
destination: '/block/:block?tab=internal_txs',
|
||||
},
|
||||
{
|
||||
source: '/txsInternal',
|
||||
destination: '/internal-txs',
|
||||
},
|
||||
{
|
||||
source: '/blocks_forked',
|
||||
destination: '/blocks?tab=reorgs',
|
||||
},
|
||||
{
|
||||
source: '/contractsVerified',
|
||||
destination: '/verified-contracts',
|
||||
},
|
||||
{
|
||||
source: '/verifyContract',
|
||||
has: [
|
||||
{ type: 'query', key: 'a' },
|
||||
],
|
||||
destination: '/address/:a/contract-verification',
|
||||
},
|
||||
{
|
||||
source: '/verifyContract',
|
||||
destination: '/contract-verification',
|
||||
},
|
||||
{
|
||||
source: '/tokentxns',
|
||||
destination: '/token-transfers',
|
||||
},
|
||||
{
|
||||
source: '/nft/:hash/:id',
|
||||
destination: '/token/:hash/instance/:id',
|
||||
},
|
||||
{
|
||||
source: '/charts',
|
||||
destination: '/stats',
|
||||
},
|
||||
{
|
||||
source: '/nft-latest-mints',
|
||||
destination: '/advanced-filter?transaction_types=ERC-1155%2CERC-721&methods=0xa0712d68&methods_names=mint',
|
||||
},
|
||||
{
|
||||
source: '/nft-transfers',
|
||||
destination: '/advanced-filter?transaction_types=ERC-1155%2CERC-721',
|
||||
},
|
||||
{
|
||||
source: '/name-lookup-search',
|
||||
destination: '/name-domains',
|
||||
},
|
||||
{
|
||||
source: '/txsExit',
|
||||
destination: '/withdrawals',
|
||||
},
|
||||
{
|
||||
source: '/txsEnqueued',
|
||||
destination: '/deposits',
|
||||
},
|
||||
];
|
||||
|
||||
async function redirects() {
|
||||
return [
|
||||
...oldUrls.map((item) => ({ ...item, permanent: false })),
|
||||
...OLD_UI_URLS.map((item) => ({ ...item, permanent: false })),
|
||||
...ETHERSCAN_URLS.map((item) => ({ ...item, permanent: true })),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { Route } from 'nextjs-routes';
|
||||
import { route as nextjsRoute } from 'nextjs-routes';
|
||||
|
||||
import type { TMultichainContext } from 'lib/contexts/multichain';
|
||||
|
||||
export const route = (route: Route, multichainContext?: TMultichainContext | null) => {
|
||||
return nextjsRoute(routeParams(route, multichainContext));
|
||||
};
|
||||
|
||||
export const routeParams = (route: Route, multichainContext?: TMultichainContext | null): Route => {
|
||||
if (multichainContext) {
|
||||
const pathname = '/chain/[chain-slug]' + route.pathname;
|
||||
return { ...route, pathname, query: { ...route.query, 'chain-slug': multichainContext.chain.slug } } as Route;
|
||||
}
|
||||
return route;
|
||||
};
|
||||
@@ -23,6 +23,8 @@ export default function fetchFactory(
|
||||
cookie,
|
||||
...pick(_req.headers, [
|
||||
'x-csrf-token',
|
||||
'recaptcha-v2-response',
|
||||
'user-agent',
|
||||
'Authorization', // the old value, just in case
|
||||
'authorization', // Node.js automatically lowercases headers
|
||||
// feature flags
|
||||
|
||||
+2
-1
@@ -13,7 +13,7 @@
|
||||
"dev:preset:sync": "tsc -p ./tools/preset-sync/tsconfig.json && node ./tools/preset-sync/index.js",
|
||||
"build": "next build",
|
||||
"build:next": "./deploy/scripts/download_assets.sh ./public/assets/configs && yarn svg:build-sprite && ./deploy/scripts/make_envs_script.sh && next build",
|
||||
"build:docker": "docker build --build-arg GIT_COMMIT_SHA=$(git rev-parse --short HEAD) --build-arg GIT_TAG=$(git describe --tags --abbrev=0) -t blockscout-frontend:local ./",
|
||||
"build:docker": "./tools/scripts/build.docker.sh",
|
||||
"start": "next start",
|
||||
"start:docker:local": "docker run -p 3000:3000 --env-file .env.local blockscout-frontend:local",
|
||||
"start:docker:preset": "./tools/scripts/docker.preset.sh",
|
||||
@@ -43,6 +43,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@blockscout/bens-types": "1.4.1",
|
||||
"@blockscout/multichain-aggregator-types": "1.6.0-alpha.0",
|
||||
"@blockscout/points-types": "1.3.0-alpha.2",
|
||||
"@blockscout/stats-types": "^2.9.0",
|
||||
"@blockscout/tac-operation-lifecycle-types": "0.0.1-alpha.6",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user