mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
links to other explorers
This commit is contained in:
@@ -22,3 +22,4 @@ NEXT_PUBLIC_APP_HOST=APP_NEXT_NEXT_PUBLIC_APP_HOST
|
||||
NEXT_PUBLIC_APP_PORT=APP_NEXT_NEXT_PUBLIC_APP_PORT
|
||||
NEXT_PUBLIC_API_ENDPOINT=APP_NEXT_NEXT_PUBLIC_API_ENDPOINT
|
||||
NEXT_PUBLIC_API_BASE_PATH=APP_NEXT_NEXT_PUBLIC_API_BASE_PATH
|
||||
NEXT_PUBLIC_NETWORK_EXPLORERS=APP_NEXT_NEXT_PUBLIC_NETWORK_EXPLORERS
|
||||
|
||||
@@ -66,6 +66,7 @@ The app instance could be customized by passing following variables to NodeJS en
|
||||
| NEXT_PUBLIC_FOOTER_TELEGRAM_LINK | `string` *(optional)* | Link to Telegram in the footer | `https://t.me/poa_network` |
|
||||
| NEXT_PUBLIC_FOOTER_STAKING_LINK | `string` *(optional)* | Link to staking dashboard in the footer | `https://duneanalytics.com/maxaleks/xdai-staking` |
|
||||
| NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM | `string` | Link to form where authors can submit their dapps to the marketplace | `https://airtable.com/shrqUAcjgGJ4jU88C` |
|
||||
| NEXT_PUBLIC_NETWORK_EXPLORERS | `Array<NetworkExplorer>` where `NetworkExplorer` can have following [properties](#network-explorer-configuration-properties) | Used to build up links to transactions, blocks, addresses in other chain explorers. | `[{'title':'Anyblock','baseUrl':'https://explorer.anyblock.tools','paths':{'tx':'/ethereum/poa/core/tx'}}]` |
|
||||
|
||||
### App configuration
|
||||
|
||||
@@ -93,6 +94,16 @@ The app instance could be customized by passing following variables to NodeJS en
|
||||
| group | `mainnets \| testnets \| other` | Indicates in which tab network appears in the menu | `'mainnets'` |
|
||||
| icon | `string` *(optional)* | Network icon; if not provided, will fallback to icon predefined in the project; if the project doesn't have icon for such network then the common placeholder will be shown; *Note* that icon size should be 30px by 30px | `'https://www.fillmurray.com/60/60'` |
|
||||
|
||||
### Network explorer configuration properties
|
||||
|
||||
| Property | Type | Description | Example value
|
||||
| --- | --- | --- | --- |
|
||||
| title | `string` | Displayed name of the explorer | `'Anyblock'` |
|
||||
| baseUrl | `string` | Base url of the explorer | `'https://explorer.anyblock.tools'` |
|
||||
| paths | `Record<'tx' \| 'block' \| 'address', string>` | Map of explorer entities and their paths | `'paths':{'tx':'/ethereum/poa/core/tx'}` |
|
||||
|
||||
*Note* The url of an entity will be constructed as `<baseUrl><paths[<entity-type>]><entity-id>`, e.g `https://explorer.anyblock.tools/ethereum/poa/core/tx/<tx-id>`
|
||||
|
||||
### External services configuration
|
||||
|
||||
| Variable | Type | Description | Default value
|
||||
|
||||
@@ -22,6 +22,7 @@ const config = Object.freeze({
|
||||
assetsPathname: process.env.NEXT_PUBLIC_NETWORK_ASSETS_PATHNAME,
|
||||
nativeTokenAddress: process.env.NEXT_PUBLIC_NETWORK_TOKEN_ADDRESS,
|
||||
basePath: '/' + [ process.env.NEXT_PUBLIC_NETWORK_TYPE, process.env.NEXT_PUBLIC_NETWORK_SUBTYPE ].filter(Boolean).join('/'),
|
||||
explorers: process.env.NEXT_PUBLIC_NETWORK_EXPLORERS?.replaceAll('\'', '"'),
|
||||
},
|
||||
footerLinks: {
|
||||
github: process.env.NEXT_PUBLIC_FOOTER_GITHUB_LINK,
|
||||
|
||||
@@ -4,7 +4,7 @@ NEXT_PUBLIC_APP_HOST=localhost
|
||||
NEXT_PUBLIC_APP_PORT=3000
|
||||
NEXT_PUBLIC_APP_INSTANCE=local
|
||||
|
||||
# nav and footer config
|
||||
# ui config
|
||||
NEXT_PUBLIC_BLOCKSCOUT_VERSION=v4.1.7-beta
|
||||
NEXT_PUBLIC_FOOTER_GITHUB_LINK=https://github.com/blockscout/blockscout
|
||||
NEXT_PUBLIC_FOOTER_TWITTER_LINK=https://www.twitter.com/blockscoutcom
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# nav and footer config
|
||||
# ui config
|
||||
NEXT_PUBLIC_FOOTER_TELEGRAM_LINK=https://t.me/poa_network
|
||||
NEXT_PUBLIC_FOOTER_STAKING_LINK=https://duneanalytics.com/maxaleks/xdai-staking
|
||||
NEXT_PUBLIC_FEATURED_NETWORKS=[{'title':'Gnosis Chain','basePath':'/xdai/mainnet','group':'mainnets'},{'title':'Optimism on Gnosis Chain','basePath':'/xdai/optimism','group':'mainnets','icon':'https://www.fillmurray.com/60/60'},{'title':'Arbitrum on xDai','basePath':'/xdai/aox','group':'mainnets'},{'title':'Ethereum','basePath':'/eth/mainnet','group':'mainnets'},{'title':'Ethereum Classic','basePath':'/etx/mainnet','group':'mainnets'},{'title':'POA','basePath':'/poa/core','group':'mainnets'},{'title':'RSK','basePath':'/rsk/mainnet','group':'mainnets'},{'title':'Gnosis Chain Testnet','basePath':'/xdai/testnet','group':'testnets'},{'title':'POA Sokol','basePath':'/poa/sokol','group':'testnets'},{'title':'ARTIS Σ1','basePath':'/artis/sigma1','group':'other'},{'title':'LUKSO L14','basePath':'/lukso/l14','group':'other'},{'title':'Astar','basePath':'/astar','group':'other'}]
|
||||
NEXT_PUBLIC_NETWORK_EXPLORERS=[{'title':'Anyblock','baseUrl':'https://explorer.anyblock.tools','paths':{'tx':'/ethereum/poa/core/tx'}}]
|
||||
|
||||
# current network config
|
||||
NEXT_PUBLIC_NETWORK_NAME=POA
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import appConfig from 'configs/app/config';
|
||||
import _compose from 'lodash/fp/compose';
|
||||
import _mapValues from 'lodash/mapValues';
|
||||
|
||||
import type { NetworkExplorer } from 'types/networks';
|
||||
|
||||
// for easy .env update
|
||||
// const NETWORK_EXPLORERS = JSON.stringify([
|
||||
// {
|
||||
// title: 'Anyblock',
|
||||
// baseUrl: 'https://explorer.anyblock.tools',
|
||||
// paths: {
|
||||
// tx: '/ethereum/poa/core/tx',
|
||||
// },
|
||||
// },
|
||||
// ]).replaceAll('"', '\'');
|
||||
|
||||
function parseNetworkExplorers() {
|
||||
try {
|
||||
return JSON.parse(appConfig.network.explorers || '[]');
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
const stripTrailingSlash = (str: string) => str.at(-1) === '/' ? str.slice(0, -1) : str;
|
||||
const addLeadingSlash = (str: string) => str.at(0) === '/' ? str : '/' + str;
|
||||
|
||||
const networkExplorers: Array<NetworkExplorer> = (() => {
|
||||
const explorers: Array<NetworkExplorer> = parseNetworkExplorers();
|
||||
return explorers.map((explorer) => ({
|
||||
...explorer,
|
||||
baseUrl: stripTrailingSlash(explorer.baseUrl),
|
||||
paths: _mapValues(explorer.paths, _compose(stripTrailingSlash, addLeadingSlash)),
|
||||
}));
|
||||
})();
|
||||
|
||||
export default networkExplorers;
|
||||
@@ -8,3 +8,11 @@ export interface FeaturedNetwork {
|
||||
group: NetworkGroup;
|
||||
icon?: FunctionComponent<SVGAttributes<SVGElement>> | string;
|
||||
}
|
||||
|
||||
export interface NetworkExplorer {
|
||||
title: string;
|
||||
baseUrl: string;
|
||||
paths: {
|
||||
tx: string;
|
||||
};
|
||||
}
|
||||
|
||||
+24
-13
@@ -1,10 +1,12 @@
|
||||
import { Flex, Link, Icon } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
import type { RoutedTab } from 'ui/shared/RoutedTabs/types';
|
||||
|
||||
import eastArrowIcon from 'icons/arrows/east.svg';
|
||||
import link from 'lib/link/link';
|
||||
import networkExplorers from 'lib/networks/networkExplorers';
|
||||
import ExternalLink from 'ui/shared/ExternalLink';
|
||||
import Page from 'ui/shared/Page/Page';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
@@ -25,6 +27,15 @@ const TABS: Array<RoutedTab> = [
|
||||
];
|
||||
|
||||
const TransactionPageContent = () => {
|
||||
const router = useRouter();
|
||||
|
||||
const explorersLinks = networkExplorers
|
||||
.filter((explorer) => explorer.paths.tx)
|
||||
.map((explorer) => {
|
||||
const url = new URL(explorer.paths.tx + '/' + router.query.id, explorer.baseUrl);
|
||||
return <ExternalLink key={ explorer.baseUrl } title={ `Open in ${ explorer.title }` } href={ url.toString() }/>;
|
||||
});
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{ /* TODO should be shown only when navigating from txs list */ }
|
||||
@@ -34,19 +45,19 @@ const TransactionPageContent = () => {
|
||||
</Link>
|
||||
<Flex alignItems="flex-start" flexDir={{ base: 'column', lg: 'row' }}>
|
||||
<PageTitle text="Transaction details"/>
|
||||
<Flex
|
||||
alignItems="center"
|
||||
flexWrap="wrap"
|
||||
columnGap={ 6 }
|
||||
rowGap={ 3 }
|
||||
ml={{ base: 'initial', lg: 'auto' }}
|
||||
mb={{ base: 6, lg: 'initial' }}
|
||||
py={ 2.5 }
|
||||
>
|
||||
<ExternalLink title="Open in Tenderly" href="#"/>
|
||||
<ExternalLink title="Open in Blockchair" href="#"/>
|
||||
<ExternalLink title="Open in Etherscan" href="#"/>
|
||||
</Flex>
|
||||
{ explorersLinks.length > 0 && (
|
||||
<Flex
|
||||
alignItems="center"
|
||||
flexWrap="wrap"
|
||||
columnGap={ 6 }
|
||||
rowGap={ 3 }
|
||||
ml={{ base: 'initial', lg: 'auto' }}
|
||||
mb={{ base: 6, lg: 'initial' }}
|
||||
py={ 2.5 }
|
||||
>
|
||||
{ explorersLinks }
|
||||
</Flex>
|
||||
) }
|
||||
</Flex>
|
||||
<RoutedTabs
|
||||
tabs={ TABS }
|
||||
|
||||
Reference in New Issue
Block a user