Commit fd349bbb authored by tom's avatar tom

address routes

parent f3ecc07e
...@@ -38,56 +38,56 @@ const oldUrls = [ ...@@ -38,56 +38,56 @@ const oldUrls = [
newPath: `${ PATHS.block }?tab=txs`, newPath: `${ PATHS.block }?tab=txs`,
}, },
{ {
oldPath: '/address/:id/transactions', oldPath: '/address/:hash/transactions',
newPath: `${ PATHS.address_index }`, newPath: `${ PATHS.address_index }`,
}, },
{ {
oldPath: '/address/:id/token-transfers', oldPath: '/address/:hash/token-transfers',
newPath: `${ PATHS.address_index }?tab=token_transfers`, newPath: `${ PATHS.address_index }?tab=token_transfers`,
}, },
{ {
oldPath: '/address/:id/tokens', oldPath: '/address/:hash/tokens',
newPath: `${ PATHS.address_index }?tab=tokens`, newPath: `${ PATHS.address_index }?tab=tokens`,
}, },
{ {
oldPath: '/address/:id/internal-transactions', oldPath: '/address/:hash/internal-transactions',
newPath: `${ PATHS.address_index }?tab=internal_txns`, newPath: `${ PATHS.address_index }?tab=internal_txns`,
}, },
{ {
oldPath: '/address/:id/coin-balances', oldPath: '/address/:hash/coin-balances',
newPath: `${ PATHS.address_index }?tab=coin_balance_history`, newPath: `${ PATHS.address_index }?tab=coin_balance_history`,
}, },
{ {
oldPath: '/address/:id/validations', oldPath: '/address/:hash/validations',
newPath: `${ PATHS.address_index }?tab=blocks_validated`, newPath: `${ PATHS.address_index }?tab=blocks_validated`,
}, },
{ {
oldPath: '/address/:id/tokens/:hash/token-transfers', oldPath: '/address/:hash/tokens/:token_hash/token-transfers',
newPath: `${ PATHS.address_index }?tab=token_transfers&token=:hash`, newPath: `${ PATHS.address_index }?tab=token_transfers&token=:token_hash`,
}, },
// contract verification // contract verification
{ {
oldPath: '/address/:id/contract_verifications/new', oldPath: '/address/:hash/contract_verifications/new',
newPath: `${ PATHS.address_contract_verification }`, newPath: `${ PATHS.address_contract_verification }`,
}, },
{ {
oldPath: '/address/:id/verify-via-flattened-code/new', oldPath: '/address/:hash/verify-via-flattened-code/new',
newPath: `${ PATHS.address_contract_verification }?method=flatten_source_code`, newPath: `${ PATHS.address_contract_verification }?method=flatten_source_code`,
}, },
{ {
oldPath: '/address/:id/verify-via-standard-json-input/new', oldPath: '/address/:hash/verify-via-standard-json-input/new',
newPath: `${ PATHS.address_contract_verification }?method=standard_input`, newPath: `${ PATHS.address_contract_verification }?method=standard_input`,
}, },
{ {
oldPath: '/address/:id/verify-via-metadata-json/new', oldPath: '/address/:hash/verify-via-metadata-json/new',
newPath: `${ PATHS.address_contract_verification }?method=sourcify`, newPath: `${ PATHS.address_contract_verification }?method=sourcify`,
}, },
{ {
oldPath: '/address/:id/verify-via-multi-part-files/new', oldPath: '/address/:hash/verify-via-multi-part-files/new',
newPath: `${ PATHS.address_contract_verification }?method=multi_part_file`, newPath: `${ PATHS.address_contract_verification }?method=multi_part_file`,
}, },
{ {
oldPath: '/address/:id/verify-vyper-contract/new', oldPath: '/address/:hash/verify-vyper-contract/new',
newPath: `${ PATHS.address_contract_verification }?method=vyper_contract`, newPath: `${ PATHS.address_contract_verification }?method=vyper_contract`,
}, },
]; ];
......
...@@ -145,78 +145,78 @@ export const RESOURCES = { ...@@ -145,78 +145,78 @@ export const RESOURCES = {
// ADDRESS // ADDRESS
address: { address: {
path: '/api/v2/addresses/:id', path: '/api/v2/addresses/:hash',
}, },
address_counters: { address_counters: {
path: '/api/v2/addresses/:id/counters', path: '/api/v2/addresses/:hash/counters',
}, },
// this resource doesn't have pagination, so causing huge problems on some addresses page // this resource doesn't have pagination, so causing huge problems on some addresses page
// address_token_balances: { // address_token_balances: {
// path: '/api/v2/addresses/:id/token-balances', // path: '/api/v2/addresses/:hash/token-balances',
// }, // },
address_txs: { address_txs: {
path: '/api/v2/addresses/:id/transactions', path: '/api/v2/addresses/:hash/transactions',
paginationFields: [ 'block_number' as const, 'items_count' as const, 'index' as const ], paginationFields: [ 'block_number' as const, 'items_count' as const, 'index' as const ],
filterFields: [ 'filter' as const ], filterFields: [ 'filter' as const ],
}, },
address_internal_txs: { address_internal_txs: {
path: '/api/v2/addresses/:id/internal-transactions', path: '/api/v2/addresses/:hash/internal-transactions',
paginationFields: [ 'block_number' as const, 'items_count' as const, 'index' as const, 'transaction_index' as const ], paginationFields: [ 'block_number' as const, 'items_count' as const, 'index' as const, 'transaction_index' as const ],
filterFields: [ 'filter' as const ], filterFields: [ 'filter' as const ],
}, },
address_token_transfers: { address_token_transfers: {
path: '/api/v2/addresses/:id/token-transfers', path: '/api/v2/addresses/:hash/token-transfers',
paginationFields: [ 'block_number' as const, 'items_count' as const, 'index' as const, 'transaction_index' as const ], paginationFields: [ 'block_number' as const, 'items_count' as const, 'index' as const, 'transaction_index' as const ],
filterFields: [ 'filter' as const, 'type' as const, 'token' as const ], filterFields: [ 'filter' as const, 'type' as const, 'token' as const ],
}, },
address_blocks_validated: { address_blocks_validated: {
path: '/api/v2/addresses/:id/blocks-validated', path: '/api/v2/addresses/:hash/blocks-validated',
paginationFields: [ 'items_count' as const, 'block_number' as const ], paginationFields: [ 'items_count' as const, 'block_number' as const ],
filterFields: [ ], filterFields: [ ],
}, },
address_coin_balance: { address_coin_balance: {
path: '/api/v2/addresses/:id/coin-balance-history', path: '/api/v2/addresses/:hash/coin-balance-history',
paginationFields: [ 'items_count' as const, 'block_number' as const ], paginationFields: [ 'items_count' as const, 'block_number' as const ],
filterFields: [ ], filterFields: [ ],
}, },
address_coin_balance_chart: { address_coin_balance_chart: {
path: '/api/v2/addresses/:id/coin-balance-history-by-day', path: '/api/v2/addresses/:hash/coin-balance-history-by-day',
}, },
address_logs: { address_logs: {
path: '/api/v2/addresses/:id/logs', path: '/api/v2/addresses/:hash/logs',
paginationFields: [ 'items_count' as const, 'transaction_index' as const, 'index' as const, 'block_number' as const ], paginationFields: [ 'items_count' as const, 'transaction_index' as const, 'index' as const, 'block_number' as const ],
filterFields: [ ], filterFields: [ ],
}, },
address_tokens: { address_tokens: {
path: '/api/v2/addresses/:id/tokens', path: '/api/v2/addresses/:hash/tokens',
paginationFields: [ 'items_count' as const, 'token_name' as const, 'token_type' as const, 'value' as const ], paginationFields: [ 'items_count' as const, 'token_name' as const, 'token_type' as const, 'value' as const ],
filterFields: [ 'type' as const ], filterFields: [ 'type' as const ],
}, },
// CONTRACT // CONTRACT
contract: { contract: {
path: '/api/v2/smart-contracts/:id', path: '/api/v2/smart-contracts/:hash',
}, },
contract_methods_read: { contract_methods_read: {
path: '/api/v2/smart-contracts/:id/methods-read', path: '/api/v2/smart-contracts/:hash/methods-read',
}, },
contract_methods_read_proxy: { contract_methods_read_proxy: {
path: '/api/v2/smart-contracts/:id/methods-read-proxy', path: '/api/v2/smart-contracts/:hash/methods-read-proxy',
}, },
contract_method_query: { contract_method_query: {
path: '/api/v2/smart-contracts/:id/query-read-method', path: '/api/v2/smart-contracts/:hash/query-read-method',
}, },
contract_methods_write: { contract_methods_write: {
path: '/api/v2/smart-contracts/:id/methods-write', path: '/api/v2/smart-contracts/:hash/methods-write',
}, },
contract_methods_write_proxy: { contract_methods_write_proxy: {
path: '/api/v2/smart-contracts/:id/methods-write-proxy', path: '/api/v2/smart-contracts/:hash/methods-write-proxy',
}, },
contract_verification_config: { contract_verification_config: {
path: '/api/v2/smart-contracts/verification/config', path: '/api/v2/smart-contracts/verification/config',
}, },
contract_verification_via: { contract_verification_via: {
path: '/api/v2/smart-contracts/:id/verification/via/:method', path: '/api/v2/smart-contracts/:hash/verification/via/:method',
}, },
// TOKEN // TOKEN
......
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
"custom_abi": "/account/custom_abi", "custom_abi": "/account/custom_abi",
"profile": "/auth/profile", "profile": "/auth/profile",
"txs": "/txs", "txs": "/txs",
"tx": "/tx/:id", "tx": "/tx/:hash",
"blocks": "/blocks", "blocks": "/blocks",
"block": "/block/:height", "block": "/block/:height",
"tokens": "/tokens", "tokens": "/tokens",
"token_index": "/token/:hash", "token_index": "/token/:hash",
"token_instance_item": "/token/:hash/instance/:id", "token_instance_item": "/token/:hash/instance/:id",
"address_index": "/address/:id", "address_index": "/address/:hash",
"address_contract_verification": "/address/:id/contract_verification", "address_contract_verification": "/address/:hash/contract_verification",
"accounts": "/accounts", "accounts": "/accounts",
"apps": "/apps", "apps": "/apps",
"app_index": "/apps/:id", "app_index": "/apps/:id",
......
...@@ -69,14 +69,14 @@ export const ROUTES = { ...@@ -69,14 +69,14 @@ export const ROUTES = {
}, },
// ADDRESSES // ADDRESSES
address_index: { // address_index: {
pattern: PATHS.address_index, // pattern: PATHS.address_index,
crossNetworkNavigation: true, // crossNetworkNavigation: true,
}, // },
address_contract_verification: { // address_contract_verification: {
pattern: PATHS.address_contract_verification, // pattern: PATHS.address_contract_verification,
crossNetworkNavigation: true, // crossNetworkNavigation: true,
}, // },
// ACCOUNTS // ACCOUNTS
// accounts: { // accounts: {
......
import type { PageParams } from './types'; import type { RoutedQuery } from 'nextjs-routes';
import getNetworkTitle from 'lib/networks/getNetworkTitle'; import getNetworkTitle from 'lib/networks/getNetworkTitle';
export default function getSeo(params: PageParams) { export default function getSeo(params: RoutedQuery<'/address/[hash]'>) {
const networkTitle = getNetworkTitle(); const networkTitle = getNetworkTitle();
return { return {
title: params ? `${ params.id } - ${ networkTitle }` : '', title: params ? `${ params.hash } - ${ networkTitle }` : '',
description: params ? description: params ?
`View the account balance, transactions, and other data for ${ params.id } on the ${ networkTitle }` : `View the account balance, transactions, and other data for ${ params.hash } on the ${ networkTitle }` :
'', '',
}; };
} }
export type PageParams = {
id: string;
}
import type { NextPage } from 'next'; import type { NextPage } from 'next';
import Head from 'next/head'; import Head from 'next/head';
import type { RoutedQuery } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import type { PageParams } from 'lib/next/address/types';
import getSeo from 'lib/next/address/getSeo'; import getSeo from 'lib/next/address/getSeo';
import ContractVerification from 'ui/pages/ContractVerification'; import ContractVerification from 'ui/pages/ContractVerification';
const ContractVerificationPage: NextPage<PageParams> = ({ id }: PageParams) => { const ContractVerificationPage: NextPage<RoutedQuery<'/address/[hash]/contract_verification'>> =
const { title, description } = getSeo({ id }); ({ hash }: RoutedQuery<'/address/[hash]/contract_verification'>) => {
const { title, description } = getSeo({ hash });
return ( return (
<> <>
......
import type { NextPage } from 'next'; import type { NextPage } from 'next';
import Head from 'next/head'; import Head from 'next/head';
import type { RoutedQuery } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import type { PageParams } from 'lib/next/address/types';
import getSeo from 'lib/next/address/getSeo'; import getSeo from 'lib/next/address/getSeo';
import Address from 'ui/pages/Address'; import Address from 'ui/pages/Address';
const AddressPage: NextPage<PageParams> = ({ id }: PageParams) => { const AddressPage: NextPage<RoutedQuery<'/address/[hash]'>> = ({ hash }: RoutedQuery<'/address/[hash]'>) => {
const { title, description } = getSeo({ id }); const { title, description } = getSeo({ hash });
return ( return (
<> <>
......
...@@ -7,7 +7,6 @@ import type { SearchRedirectResult } from 'types/api/search'; ...@@ -7,7 +7,6 @@ import type { SearchRedirectResult } from 'types/api/search';
import buildUrlNode from 'lib/api/buildUrlNode'; import buildUrlNode from 'lib/api/buildUrlNode';
import fetchFactory from 'lib/api/nodeFetch'; import fetchFactory from 'lib/api/nodeFetch';
import link from 'lib/link/link';
import getNetworkTitle from 'lib/networks/getNetworkTitle'; import getNetworkTitle from 'lib/networks/getNetworkTitle';
import type { Props } from 'lib/next/getServerSideProps'; import type { Props } from 'lib/next/getServerSideProps';
import { getServerSideProps as getServerSidePropsBase } from 'lib/next/getServerSideProps'; import { getServerSideProps as getServerSidePropsBase } from 'lib/next/getServerSideProps';
...@@ -47,7 +46,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async({ req, res, r ...@@ -47,7 +46,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async({ req, res, r
return route({ pathname: '/block/[height]', query: { height: q } }); return route({ pathname: '/block/[height]', query: { height: q } });
} }
case 'address': { case 'address': {
return link('address_index', { id: payload.parameter || q }); return route({ pathname: '/address/[hash]', query: { hash: payload.parameter || q } });
} }
case 'transaction': { case 'transaction': {
return route({ pathname: '/tx/[hash]', query: { hash: q } }); return route({ pathname: '/tx/[hash]', query: { hash: q } });
......
...@@ -12,8 +12,8 @@ declare module "nextjs-routes" { ...@@ -12,8 +12,8 @@ declare module "nextjs-routes" {
| StaticRoute<"/account/tag_address"> | StaticRoute<"/account/tag_address">
| StaticRoute<"/account/watchlist"> | StaticRoute<"/account/watchlist">
| StaticRoute<"/accounts"> | StaticRoute<"/accounts">
| DynamicRoute<"/address/[id]/contract_verification", { "id": string }> | DynamicRoute<"/address/[hash]/contract_verification", { "hash": string }>
| DynamicRoute<"/address/[id]", { "id": string }> | DynamicRoute<"/address/[hash]", { "hash": string }>
| StaticRoute<"/api/csrf"> | StaticRoute<"/api/csrf">
| StaticRoute<"/api/proxy"> | StaticRoute<"/api/proxy">
| DynamicRoute<"/apps/[id]", { "id": string }> | DynamicRoute<"/apps/[id]", { "id": string }>
......
...@@ -31,10 +31,10 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => { ...@@ -31,10 +31,10 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const router = useRouter(); const router = useRouter();
const addressHash = String(router.query?.id); const addressHash = String(router.query.hash);
const query = useQueryWithPages({ const query = useQueryWithPages({
resourceName: 'address_blocks_validated', resourceName: 'address_blocks_validated',
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
scrollRef, scrollRef,
}); });
...@@ -46,7 +46,7 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => { ...@@ -46,7 +46,7 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
setSocketAlert(false); setSocketAlert(false);
queryClient.setQueryData( queryClient.setQueryData(
getResourceKey('address_blocks_validated', { pathParams: { id: addressHash } }), getResourceKey('address_blocks_validated', { pathParams: { hash: addressHash } }),
(prevData: AddressBlocksValidatedResponse | undefined) => { (prevData: AddressBlocksValidatedResponse | undefined) => {
if (!prevData) { if (!prevData) {
return; return;
......
...@@ -8,11 +8,11 @@ import buildApiUrl from 'playwright/utils/buildApiUrl'; ...@@ -8,11 +8,11 @@ import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressCoinBalance from './AddressCoinBalance'; import AddressCoinBalance from './AddressCoinBalance';
const addressHash = 'hash'; const addressHash = 'hash';
const BALANCE_HISTORY_API_URL = buildApiUrl('address_coin_balance', { id: addressHash }); const BALANCE_HISTORY_API_URL = buildApiUrl('address_coin_balance', { hash: addressHash });
const BALANCE_HISTORY_CHART_API_URL = buildApiUrl('address_coin_balance_chart', { id: addressHash }); const BALANCE_HISTORY_CHART_API_URL = buildApiUrl('address_coin_balance_chart', { hash: addressHash });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: addressHash }, query: { hash: addressHash },
}, },
}; };
......
...@@ -7,6 +7,7 @@ import type { AddressCoinBalanceHistoryResponse } from 'types/api/address'; ...@@ -7,6 +7,7 @@ import type { AddressCoinBalanceHistoryResponse } from 'types/api/address';
import { getResourceKey } from 'lib/api/useApiQuery'; import { getResourceKey } from 'lib/api/useApiQuery';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
import SocketAlert from 'ui/shared/SocketAlert'; import SocketAlert from 'ui/shared/SocketAlert';
...@@ -20,10 +21,10 @@ const AddressCoinBalance = () => { ...@@ -20,10 +21,10 @@ const AddressCoinBalance = () => {
const router = useRouter(); const router = useRouter();
const scrollRef = React.useRef<HTMLDivElement>(null); const scrollRef = React.useRef<HTMLDivElement>(null);
const addressHash = String(router.query?.id); const addressHash = getQueryParamString(router.query.hash);
const coinBalanceQuery = useQueryWithPages({ const coinBalanceQuery = useQueryWithPages({
resourceName: 'address_coin_balance', resourceName: 'address_coin_balance',
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
scrollRef, scrollRef,
}); });
...@@ -35,7 +36,7 @@ const AddressCoinBalance = () => { ...@@ -35,7 +36,7 @@ const AddressCoinBalance = () => {
setSocketAlert(false); setSocketAlert(false);
queryClient.setQueryData( queryClient.setQueryData(
getResourceKey('address_coin_balance', { pathParams: { id: addressHash } }), getResourceKey('address_coin_balance', { pathParams: { hash: addressHash } }),
(prevData: AddressCoinBalanceHistoryResponse | undefined) => { (prevData: AddressCoinBalanceHistoryResponse | undefined) => {
if (!prevData) { if (!prevData) {
return; return;
......
...@@ -21,6 +21,7 @@ const AddressCsvExportLink = ({ className, address, type }: Props) => { ...@@ -21,6 +21,7 @@ const AddressCsvExportLink = ({ className, address, type }: Props) => {
display="inline-flex" display="inline-flex"
alignItems="center" alignItems="center"
href={ link('csv_export', undefined, { type, address }) } href={ link('csv_export', undefined, { type, address }) }
flexShrink={ 0 }
> >
<Icon as={ svgFileIcon } boxSize={{ base: '30px', lg: 6 }}/> <Icon as={ svgFileIcon } boxSize={{ base: '30px', lg: 6 }}/>
<Hide ssr={ false } below="lg"><chakra.span ml={ 1 }>Download CSV</chakra.span></Hide> <Hide ssr={ false } below="lg"><chakra.span ml={ 1 }>Download CSV</chakra.span></Hide>
......
...@@ -16,14 +16,14 @@ import AddressDetails from './AddressDetails'; ...@@ -16,14 +16,14 @@ import AddressDetails from './AddressDetails';
import MockAddressPage from './testUtils/MockAddressPage'; import MockAddressPage from './testUtils/MockAddressPage';
const ADDRESS_HASH = addressMock.hash; const ADDRESS_HASH = addressMock.hash;
const API_URL_ADDRESS = buildApiUrl('address', { id: ADDRESS_HASH }); const API_URL_ADDRESS = buildApiUrl('address', { hash: ADDRESS_HASH });
const API_URL_COUNTERS = buildApiUrl('address_counters', { id: ADDRESS_HASH }); const API_URL_COUNTERS = buildApiUrl('address_counters', { hash: ADDRESS_HASH });
const API_URL_TOKENS_ERC20 = buildApiUrl('address_tokens', { id: ADDRESS_HASH }) + '?type=ERC-20'; const API_URL_TOKENS_ERC20 = buildApiUrl('address_tokens', { hash: ADDRESS_HASH }) + '?type=ERC-20';
const API_URL_TOKENS_ERC721 = buildApiUrl('address_tokens', { id: ADDRESS_HASH }) + '?type=ERC-721'; const API_URL_TOKENS_ERC721 = buildApiUrl('address_tokens', { hash: ADDRESS_HASH }) + '?type=ERC-721';
const API_URL_TOKENS_ER1155 = buildApiUrl('address_tokens', { id: ADDRESS_HASH }) + '?type=ERC-1155'; const API_URL_TOKENS_ER1155 = buildApiUrl('address_tokens', { hash: ADDRESS_HASH }) + '?type=ERC-1155';
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: ADDRESS_HASH }, query: { hash: ADDRESS_HASH },
}, },
}; };
......
...@@ -10,7 +10,7 @@ import appConfig from 'configs/app/config'; ...@@ -10,7 +10,7 @@ import appConfig from 'configs/app/config';
import blockIcon from 'icons/block.svg'; import blockIcon from 'icons/block.svg';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import link from 'lib/link/link'; import getQueryParamString from 'lib/router/getQueryParamString';
import AddressCounterItem from 'ui/address/details/AddressCounterItem'; import AddressCounterItem from 'ui/address/details/AddressCounterItem';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import AddressHeadingInfo from 'ui/shared/AddressHeadingInfo'; import AddressHeadingInfo from 'ui/shared/AddressHeadingInfo';
...@@ -33,12 +33,12 @@ interface Props { ...@@ -33,12 +33,12 @@ interface Props {
const AddressDetails = ({ addressQuery, scrollRef }: Props) => { const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
const router = useRouter(); const router = useRouter();
const addressHash = router.query.id?.toString(); const addressHash = getQueryParamString(router.query.hash);
const countersQuery = useApiQuery('address_counters', { const countersQuery = useApiQuery('address_counters', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
queryOptions: { queryOptions: {
enabled: Boolean(router.query.id) && Boolean(addressQuery.data), enabled: Boolean(addressHash) && Boolean(addressQuery.data),
}, },
}); });
...@@ -91,7 +91,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -91,7 +91,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
<Flex mt={ 8 } columnGap={ 4 } flexWrap="wrap"> <Flex mt={ 8 } columnGap={ 4 } flexWrap="wrap">
<Text fontSize="sm">Verify with other explorers</Text> <Text fontSize="sm">Verify with other explorers</Text>
{ explorers.map((explorer) => { { explorers.map((explorer) => {
const url = new URL(explorer.paths.address + '/' + router.query.id, explorer.baseUrl); const url = new URL(explorer.paths.address + '/' + addressHash, explorer.baseUrl);
return <LinkExternal key={ explorer.baseUrl } title={ explorer.title } href={ url.toString() }/>; return <LinkExternal key={ explorer.baseUrl } title={ explorer.title } href={ url.toString() }/>;
}) } }) }
</Flex> </Flex>
...@@ -119,7 +119,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -119,7 +119,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
hint="Implementation address of the proxy contract." hint="Implementation address of the proxy contract."
columnGap={ 1 } columnGap={ 1 }
> >
<LinkInternal href={ link('address_index', { id: data.implementation_address }) } overflow="hidden"> <LinkInternal href={ route({ pathname: '/address/[hash]', query: { hash: data.implementation_address } }) } overflow="hidden">
{ data.implementation_name || <HashStringShortenDynamic hash={ data.implementation_address }/> } { data.implementation_name || <HashStringShortenDynamic hash={ data.implementation_address }/> }
</LinkInternal> </LinkInternal>
{ data.implementation_name && ( { data.implementation_name && (
......
...@@ -9,10 +9,10 @@ import buildApiUrl from 'playwright/utils/buildApiUrl'; ...@@ -9,10 +9,10 @@ import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressInternalTxs from './AddressInternalTxs'; import AddressInternalTxs from './AddressInternalTxs';
const ADDRESS_HASH = internalTxsMock.base.from.hash; const ADDRESS_HASH = internalTxsMock.base.from.hash;
const API_URL_TX_INTERNALS = buildApiUrl('address_internal_txs', { id: ADDRESS_HASH }); const API_URL_TX_INTERNALS = buildApiUrl('address_internal_txs', { hash: ADDRESS_HASH });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: ADDRESS_HASH }, query: { hash: ADDRESS_HASH },
}, },
}; };
......
import { Text, Show, Hide } from '@chakra-ui/react'; import { Text, Show, Hide } from '@chakra-ui/react';
import castArray from 'lodash/castArray';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
...@@ -9,6 +8,7 @@ import { AddressFromToFilterValues } from 'types/api/address'; ...@@ -9,6 +8,7 @@ import { AddressFromToFilterValues } from 'types/api/address';
import getFilterValueFromQuery from 'lib/getFilterValueFromQuery'; import getFilterValueFromQuery from 'lib/getFilterValueFromQuery';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import { apos } from 'lib/html-entities'; import { apos } from 'lib/html-entities';
import getQueryParamString from 'lib/router/getQueryParamString';
import AddressIntTxsSkeletonDesktop from 'ui/address/internals/AddressIntTxsSkeletonDesktop'; import AddressIntTxsSkeletonDesktop from 'ui/address/internals/AddressIntTxsSkeletonDesktop';
import AddressIntTxsSkeletonMobile from 'ui/address/internals/AddressIntTxsSkeletonMobile'; import AddressIntTxsSkeletonMobile from 'ui/address/internals/AddressIntTxsSkeletonMobile';
import AddressIntTxsTable from 'ui/address/internals/AddressIntTxsTable'; import AddressIntTxsTable from 'ui/address/internals/AddressIntTxsTable';
...@@ -27,13 +27,11 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE ...@@ -27,13 +27,11 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
const router = useRouter(); const router = useRouter();
const [ filterValue, setFilterValue ] = React.useState<AddressFromToFilter>(getFilterValue(router.query.filter)); const [ filterValue, setFilterValue ] = React.useState<AddressFromToFilter>(getFilterValue(router.query.filter));
const queryId = router.query.id; const hash = getQueryParamString(router.query.hash);
const queryIdArray = castArray(queryId);
const queryIdStr = queryIdArray[0];
const { data, isLoading, isError, pagination, onFilterChange, isPaginationVisible } = useQueryWithPages({ const { data, isLoading, isError, pagination, onFilterChange, isPaginationVisible } = useQueryWithPages({
resourceName: 'address_internal_txs', resourceName: 'address_internal_txs',
pathParams: { id: queryIdStr }, pathParams: { hash },
filters: { filter: filterValue }, filters: { filter: filterValue },
scrollRef, scrollRef,
}); });
...@@ -70,10 +68,10 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE ...@@ -70,10 +68,10 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
content = ( content = (
<> <>
<Show below="lg" ssr={ false }> <Show below="lg" ssr={ false }>
<AddressIntTxsList data={ data.items } currentAddress={ queryIdStr }/> <AddressIntTxsList data={ data.items } currentAddress={ hash }/>
</Show> </Show>
<Hide below="lg" ssr={ false }> <Hide below="lg" ssr={ false }>
<AddressIntTxsTable data={ data.items } currentAddress={ queryIdStr }/> <AddressIntTxsTable data={ data.items } currentAddress={ hash }/>
</Hide> </Hide>
</> </>
); );
...@@ -87,7 +85,7 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE ...@@ -87,7 +85,7 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
onFilterChange={ handleFilterChange } onFilterChange={ handleFilterChange }
isActive={ Boolean(filterValue) } isActive={ Boolean(filterValue) }
/> />
<AddressCsvExportLink address={ queryIdStr } type="internal-transactions" ml={{ base: 2, lg: 'auto' }}/> <AddressCsvExportLink address={ hash } type="internal-transactions" ml={{ base: 2, lg: 'auto' }}/>
{ isPaginationVisible && <Pagination ml={{ base: 'auto', lg: 8 }} { ...pagination }/> } { isPaginationVisible && <Pagination ml={{ base: 'auto', lg: 8 }} { ...pagination }/> }
</ActionBar> </ActionBar>
{ content } { content }
......
...@@ -3,6 +3,7 @@ import { useRouter } from 'next/router'; ...@@ -3,6 +3,7 @@ import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import getQueryParamString from 'lib/router/getQueryParamString';
import ActionBar from 'ui/shared/ActionBar'; import ActionBar from 'ui/shared/ActionBar';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import LogItem from 'ui/shared/logs/LogItem'; import LogItem from 'ui/shared/logs/LogItem';
...@@ -12,10 +13,10 @@ import Pagination from 'ui/shared/Pagination'; ...@@ -12,10 +13,10 @@ import Pagination from 'ui/shared/Pagination';
const AddressLogs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>}) => { const AddressLogs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>}) => {
const router = useRouter(); const router = useRouter();
const addressHash = String(router.query?.id); const hash = getQueryParamString(router.query.hash);
const { data, isLoading, isError, pagination, isPaginationVisible } = useQueryWithPages({ const { data, isLoading, isError, pagination, isPaginationVisible } = useQueryWithPages({
resourceName: 'address_logs', resourceName: 'address_logs',
pathParams: { id: addressHash }, pathParams: { hash },
scrollRef, scrollRef,
}); });
......
...@@ -8,12 +8,12 @@ import buildApiUrl from 'playwright/utils/buildApiUrl'; ...@@ -8,12 +8,12 @@ import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressTokenTransfers from './AddressTokenTransfers'; import AddressTokenTransfers from './AddressTokenTransfers';
const API_URL = buildApiUrl('address_token_transfers', { id: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859' }) + const API_URL = buildApiUrl('address_token_transfers', { hash: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859' }) +
'?token=0x1189a607CEac2f0E14867de4EB15b15C9FFB5859'; '?token_hash=0x1189a607CEac2f0E14867de4EB15b15C9FFB5859';
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859', token: '0x1189a607CEac2f0E14867de4EB15b15C9FFB5859' }, query: { hash: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859', token_hash: '0x1189a607CEac2f0E14867de4EB15b15C9FFB5859' },
}, },
}; };
......
...@@ -16,6 +16,7 @@ import getFilterValuesFromQuery from 'lib/getFilterValuesFromQuery'; ...@@ -16,6 +16,7 @@ import getFilterValuesFromQuery from 'lib/getFilterValuesFromQuery';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import { apos } from 'lib/html-entities'; import { apos } from 'lib/html-entities';
import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
import TOKEN_TYPE from 'lib/token/tokenTypes'; import TOKEN_TYPE from 'lib/token/tokenTypes';
...@@ -69,12 +70,12 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD ...@@ -69,12 +70,12 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const currentAddress = router.query.id?.toString(); const currentAddress = getQueryParamString(router.query.hash);
const [ socketAlert, setSocketAlert ] = React.useState(''); const [ socketAlert, setSocketAlert ] = React.useState('');
const [ newItemsCount, setNewItemsCount ] = React.useState(0); const [ newItemsCount, setNewItemsCount ] = React.useState(0);
const tokenFilter = router.query.token ? router.query.token.toString() : undefined; const tokenFilter = getQueryParamString(router.query.token_hash) || undefined;
const [ filters, setFilters ] = React.useState<Filters>( const [ filters, setFilters ] = React.useState<Filters>(
{ {
...@@ -85,7 +86,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD ...@@ -85,7 +86,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
const { isError, isLoading, data, pagination, onFilterChange, isPaginationVisible } = useQueryWithPages({ const { isError, isLoading, data, pagination, onFilterChange, isPaginationVisible } = useQueryWithPages({
resourceName: 'address_token_transfers', resourceName: 'address_token_transfers',
pathParams: { id: currentAddress }, pathParams: { hash: currentAddress },
filters: tokenFilter ? { token: tokenFilter } : filters, filters: tokenFilter ? { token: tokenFilter } : filters,
scrollRef, scrollRef,
}); });
...@@ -117,7 +118,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD ...@@ -117,7 +118,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
} }
} else { } else {
queryClient.setQueryData( queryClient.setQueryData(
getResourceKey('address_token_transfers', { pathParams: { id: router.query.id?.toString() }, queryParams: { ...filters } }), getResourceKey('address_token_transfers', { pathParams: { hash: currentAddress }, queryParams: { ...filters } }),
(prevData: AddressTokenTransferResponse | undefined) => { (prevData: AddressTokenTransferResponse | undefined) => {
if (!prevData) { if (!prevData) {
return; return;
...@@ -147,7 +148,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD ...@@ -147,7 +148,7 @@ const AddressTokenTransfers = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLD
}, []); }, []);
const channel = useSocketChannel({ const channel = useSocketChannel({
topic: `addresses:${ (router.query.id as string).toLowerCase() }`, topic: `addresses:${ currentAddress.toLowerCase() }`,
onSocketClose: handleSocketClose, onSocketClose: handleSocketClose,
onSocketError: handleSocketError, onSocketError: handleSocketError,
isDisabled: pagination.page !== 1 || Boolean(tokenFilter), isDisabled: pagination.page !== 1 || Boolean(tokenFilter),
......
...@@ -10,8 +10,8 @@ import buildApiUrl from 'playwright/utils/buildApiUrl'; ...@@ -10,8 +10,8 @@ import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressTokens from './AddressTokens'; import AddressTokens from './AddressTokens';
const ADDRESS_HASH = withName.hash; const ADDRESS_HASH = withName.hash;
const API_URL_ADDRESS = buildApiUrl('address', { id: ADDRESS_HASH }); const API_URL_ADDRESS = buildApiUrl('address', { hash: ADDRESS_HASH });
const API_URL_TOKENS = buildApiUrl('address_tokens', { id: ADDRESS_HASH }); const API_URL_TOKENS = buildApiUrl('address_tokens', { hash: ADDRESS_HASH });
const nextPageParams = { const nextPageParams = {
items_count: 50, items_count: 50,
...@@ -59,7 +59,7 @@ const test = base.extend({ ...@@ -59,7 +59,7 @@ const test = base.extend({
test('erc20 +@mobile +@dark-mode', async({ mount }) => { test('erc20 +@mobile +@dark-mode', async({ mount }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: ADDRESS_HASH, tab: 'tokens_erc20' }, query: { hash: ADDRESS_HASH, tab: 'tokens_erc20' },
isReady: true, isReady: true,
}, },
}; };
...@@ -78,7 +78,7 @@ test('erc20 +@mobile +@dark-mode', async({ mount }) => { ...@@ -78,7 +78,7 @@ test('erc20 +@mobile +@dark-mode', async({ mount }) => {
test('erc721 +@mobile +@dark-mode', async({ mount }) => { test('erc721 +@mobile +@dark-mode', async({ mount }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: ADDRESS_HASH, tab: 'tokens_erc721' }, query: { hash: ADDRESS_HASH, tab: 'tokens_erc721' },
isReady: true, isReady: true,
}, },
}; };
...@@ -97,7 +97,7 @@ test('erc721 +@mobile +@dark-mode', async({ mount }) => { ...@@ -97,7 +97,7 @@ test('erc721 +@mobile +@dark-mode', async({ mount }) => {
test('erc1155 +@mobile +@dark-mode', async({ mount }) => { test('erc1155 +@mobile +@dark-mode', async({ mount }) => {
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: ADDRESS_HASH, tab: 'tokens_erc1155' }, query: { hash: ADDRESS_HASH, tab: 'tokens_erc1155' },
isReady: true, isReady: true,
}, },
}; };
......
...@@ -36,7 +36,7 @@ const AddressTokens = () => { ...@@ -36,7 +36,7 @@ const AddressTokens = () => {
const tokensQuery = useQueryWithPages({ const tokensQuery = useQueryWithPages({
resourceName: 'address_tokens', resourceName: 'address_tokens',
pathParams: { id: router.query.id?.toString() }, pathParams: { hash: router.query.hash?.toString() },
filters: { type: tokenType }, filters: { type: tokenType },
scrollRef, scrollRef,
}); });
......
...@@ -8,11 +8,11 @@ import buildApiUrl from 'playwright/utils/buildApiUrl'; ...@@ -8,11 +8,11 @@ import buildApiUrl from 'playwright/utils/buildApiUrl';
import AddressTxs from './AddressTxs'; import AddressTxs from './AddressTxs';
const API_URL = buildApiUrl('address_txs', { id: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859' }); const API_URL = buildApiUrl('address_txs', { hash: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859' });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859' }, query: { hash: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859' },
}, },
}; };
......
...@@ -10,6 +10,7 @@ import { getResourceKey } from 'lib/api/useApiQuery'; ...@@ -10,6 +10,7 @@ import { getResourceKey } from 'lib/api/useApiQuery';
import getFilterValueFromQuery from 'lib/getFilterValueFromQuery'; import getFilterValueFromQuery from 'lib/getFilterValueFromQuery';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import useQueryWithPages from 'lib/hooks/useQueryWithPages'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
import ActionBar from 'ui/shared/ActionBar'; import ActionBar from 'ui/shared/ActionBar';
...@@ -31,13 +32,13 @@ const AddressTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>} ...@@ -31,13 +32,13 @@ const AddressTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>}
const [ newItemsCount, setNewItemsCount ] = React.useState(0); const [ newItemsCount, setNewItemsCount ] = React.useState(0);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const currentAddress = router.query.id?.toString(); const currentAddress = getQueryParamString(router.query.hash);
const [ filterValue, setFilterValue ] = React.useState<AddressFromToFilter>(getFilterValue(router.query.filter)); const [ filterValue, setFilterValue ] = React.useState<AddressFromToFilter>(getFilterValue(router.query.filter));
const addressTxsQuery = useQueryWithPages({ const addressTxsQuery = useQueryWithPages({
resourceName: 'address_txs', resourceName: 'address_txs',
pathParams: { id: currentAddress }, pathParams: { hash: currentAddress },
filters: { filter: filterValue }, filters: { filter: filterValue },
scrollRef, scrollRef,
}); });
...@@ -63,7 +64,7 @@ const AddressTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>} ...@@ -63,7 +64,7 @@ const AddressTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>}
} }
queryClient.setQueryData( queryClient.setQueryData(
getResourceKey('address_txs', { pathParams: { id: router.query.id?.toString() }, queryParams: { filter: filterValue } }), getResourceKey('address_txs', { pathParams: { hash: currentAddress }, queryParams: { filter: filterValue } }),
(prevData: AddressTransactionsResponse | undefined) => { (prevData: AddressTransactionsResponse | undefined) => {
if (!prevData) { if (!prevData) {
return; return;
......
...@@ -11,7 +11,7 @@ interface Props { ...@@ -11,7 +11,7 @@ interface Props {
const AddressCoinBalanceChart = ({ addressHash }: Props) => { const AddressCoinBalanceChart = ({ addressHash }: Props) => {
const { data, isLoading, isError } = useApiQuery('address_coin_balance_chart', { const { data, isLoading, isError } = useApiQuery('address_coin_balance_chart', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
}); });
const items = React.useMemo(() => data?.map(({ date, value }) => ({ const items = React.useMemo(() => data?.map(({ date, value }) => ({
......
...@@ -8,10 +8,10 @@ import buildApiUrl from 'playwright/utils/buildApiUrl'; ...@@ -8,10 +8,10 @@ import buildApiUrl from 'playwright/utils/buildApiUrl';
import ContractCode from './ContractCode'; import ContractCode from './ContractCode';
const addressHash = 'hash'; const addressHash = 'hash';
const CONTRACT_API_URL = buildApiUrl('contract', { id: addressHash }); const CONTRACT_API_URL = buildApiUrl('contract', { hash: addressHash });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: addressHash }, query: { hash: addressHash },
}, },
}; };
......
import { Flex, Skeleton, Button, Grid, GridItem, Text, Alert, Link, chakra, Box } from '@chakra-ui/react'; import { Flex, Skeleton, Button, Grid, GridItem, Text, Alert, Link, chakra, Box } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import link from 'lib/link/link'; import getQueryParamString from 'lib/router/getQueryParamString';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
...@@ -24,9 +25,9 @@ const InfoItem = ({ label, value }: { label: string; value: string }) => ( ...@@ -24,9 +25,9 @@ const InfoItem = ({ label, value }: { label: string; value: string }) => (
const ContractCode = () => { const ContractCode = () => {
const router = useRouter(); const router = useRouter();
const addressHash = router.query.id?.toString(); const addressHash = getQueryParamString(router.query.hash);
const { data, isLoading, isError } = useApiQuery('contract', { const { data, isLoading, isError } = useApiQuery('contract', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
queryOptions: { queryOptions: {
enabled: Boolean(addressHash), enabled: Boolean(addressHash),
refetchOnMount: false, refetchOnMount: false,
...@@ -60,7 +61,7 @@ const ContractCode = () => { ...@@ -60,7 +61,7 @@ const ContractCode = () => {
ml="auto" ml="auto"
mr={ 3 } mr={ 3 }
as="a" as="a"
href={ link('address_contract_verification', { id: addressHash }) } href={ route({ pathname: '/address/[hash]/contract_verification', query: { hash: addressHash } }) }
> >
Verify & publish Verify & publish
</Button> </Button>
...@@ -74,7 +75,7 @@ const ContractCode = () => { ...@@ -74,7 +75,7 @@ const ContractCode = () => {
const decoded = data.decoded_constructor_args const decoded = data.decoded_constructor_args
.map(([ value, { name, type } ], index) => { .map(([ value, { name, type } ], index) => {
const valueEl = type === 'address' ? const valueEl = type === 'address' ?
<LinkInternal href={ link('address_index', { id: value }) }>{ value }</LinkInternal> : <LinkInternal href={ route({ pathname: '/address/[hash]', query: { hash: value } }) }>{ value }</LinkInternal> :
<span>{ value }</span>; <span>{ value }</span>;
return ( return (
<Box key={ index }> <Box key={ index }>
...@@ -101,7 +102,7 @@ const ContractCode = () => { ...@@ -101,7 +102,7 @@ const ContractCode = () => {
return data.external_libraries.map((item) => ( return data.external_libraries.map((item) => (
<Box key={ item.address_hash }> <Box key={ item.address_hash }>
<chakra.span fontWeight={ 500 }>{ item.name }: </chakra.span> <chakra.span fontWeight={ 500 }>{ item.name }: </chakra.span>
<LinkInternal href={ link('address_index', { id: item.address_hash }, { tab: 'contract' }) }>{ item.address_hash }</LinkInternal> <LinkInternal href={ route({ pathname: '/address/[hash]', query: { hash: item.address_hash, tab: 'contract' } }) }>{ item.address_hash }</LinkInternal>
</Box> </Box>
)); ));
})(); })();
...@@ -129,7 +130,7 @@ const ContractCode = () => { ...@@ -129,7 +130,7 @@ const ContractCode = () => {
<AddressLink type="address" hash={ data.verified_twin_address_hash } truncation="constant" ml={ 2 }/> <AddressLink type="address" hash={ data.verified_twin_address_hash } truncation="constant" ml={ 2 }/>
</Address> </Address>
<chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span> <chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span>
<LinkInternal href={ link('address_contract_verification', { id: addressHash }) }>Verify & Publish</LinkInternal> <LinkInternal href={ route({ pathname: '/address/[hash]/contract_verification', query: { hash: addressHash } }) }>Verify & Publish</LinkInternal>
<span> page</span> <span> page</span>
</Alert> </Alert>
) } ) }
......
...@@ -14,7 +14,7 @@ interface Props { ...@@ -14,7 +14,7 @@ interface Props {
const ContractImplementationAddress = ({ hash }: Props) => { const ContractImplementationAddress = ({ hash }: Props) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const data = queryClient.getQueryData<TAddress>(getResourceKey('address', { const data = queryClient.getQueryData<TAddress>(getResourceKey('address', {
pathParams: { id: hash }, pathParams: { hash },
})); }));
if (!data?.implementation_address) { if (!data?.implementation_address) {
......
...@@ -8,11 +8,11 @@ import buildApiUrl from 'playwright/utils/buildApiUrl'; ...@@ -8,11 +8,11 @@ import buildApiUrl from 'playwright/utils/buildApiUrl';
import ContractRead from './ContractRead'; import ContractRead from './ContractRead';
const addressHash = 'hash'; const addressHash = 'hash';
const CONTRACT_READ_METHODS_API_URL = buildApiUrl('contract_methods_read', { id: addressHash }) + '?is_custom_abi=false'; const CONTRACT_READ_METHODS_API_URL = buildApiUrl('contract_methods_read', { hash: addressHash }) + '?is_custom_abi=false';
const CONTRACT_QUERY_METHOD_API_URL = buildApiUrl('contract_method_query', { id: addressHash }); const CONTRACT_QUERY_METHOD_API_URL = buildApiUrl('contract_method_query', { hash: addressHash });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: addressHash }, query: { hash: addressHash },
}, },
}; };
......
...@@ -7,6 +7,7 @@ import type { SmartContractReadMethod, SmartContractQueryMethodRead } from 'type ...@@ -7,6 +7,7 @@ import type { SmartContractReadMethod, SmartContractQueryMethodRead } from 'type
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import getQueryParamString from 'lib/router/getQueryParamString';
import ContractMethodsAccordion from 'ui/address/contract/ContractMethodsAccordion'; import ContractMethodsAccordion from 'ui/address/contract/ContractMethodsAccordion';
import ContentLoader from 'ui/shared/ContentLoader'; import ContentLoader from 'ui/shared/ContentLoader';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
...@@ -28,21 +29,21 @@ const ContractRead = ({ isProxy, isCustomAbi }: Props) => { ...@@ -28,21 +29,21 @@ const ContractRead = ({ isProxy, isCustomAbi }: Props) => {
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
const { address: userAddress } = useAccount(); const { address: userAddress } = useAccount();
const addressHash = router.query.id?.toString(); const addressHash = getQueryParamString(router.query.hash);
const { data, isLoading, isError } = useApiQuery(isProxy ? 'contract_methods_read_proxy' : 'contract_methods_read', { const { data, isLoading, isError } = useApiQuery(isProxy ? 'contract_methods_read_proxy' : 'contract_methods_read', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
queryParams: { queryParams: {
is_custom_abi: isCustomAbi ? 'true' : 'false', is_custom_abi: isCustomAbi ? 'true' : 'false',
}, },
queryOptions: { queryOptions: {
enabled: Boolean(router.query.id), enabled: Boolean(addressHash),
}, },
}); });
const handleMethodFormSubmit = React.useCallback(async(item: SmartContractReadMethod, args: Array<string | Array<string>>) => { const handleMethodFormSubmit = React.useCallback(async(item: SmartContractReadMethod, args: Array<string | Array<string>>) => {
return apiFetch<'contract_method_query', SmartContractQueryMethodRead>('contract_method_query', { return apiFetch<'contract_method_query', SmartContractQueryMethodRead>('contract_method_query', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
fetchParams: { fetchParams: {
method: 'POST', method: 'POST',
body: { body: {
......
...@@ -8,10 +8,10 @@ import buildApiUrl from 'playwright/utils/buildApiUrl'; ...@@ -8,10 +8,10 @@ import buildApiUrl from 'playwright/utils/buildApiUrl';
import ContractWrite from './ContractWrite'; import ContractWrite from './ContractWrite';
const addressHash = 'hash'; const addressHash = 'hash';
const CONTRACT_WRITE_METHODS_API_URL = buildApiUrl('contract_methods_write', { id: addressHash }) + '?is_custom_abi=false'; const CONTRACT_WRITE_METHODS_API_URL = buildApiUrl('contract_methods_write', { hash: addressHash }) + '?is_custom_abi=false';
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: addressHash }, query: { hash: addressHash },
}, },
}; };
......
...@@ -7,6 +7,7 @@ import type { SmartContractWriteMethod } from 'types/api/contract'; ...@@ -7,6 +7,7 @@ import type { SmartContractWriteMethod } from 'types/api/contract';
import config from 'configs/app/config'; import config from 'configs/app/config';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import getQueryParamString from 'lib/router/getQueryParamString';
import ContractMethodsAccordion from 'ui/address/contract/ContractMethodsAccordion'; import ContractMethodsAccordion from 'ui/address/contract/ContractMethodsAccordion';
import ContentLoader from 'ui/shared/ContentLoader'; import ContentLoader from 'ui/shared/ContentLoader';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
...@@ -27,12 +28,12 @@ interface Props { ...@@ -27,12 +28,12 @@ interface Props {
const ContractWrite = ({ isProxy, isCustomAbi }: Props) => { const ContractWrite = ({ isProxy, isCustomAbi }: Props) => {
const router = useRouter(); const router = useRouter();
const addressHash = router.query.id?.toString(); const addressHash = getQueryParamString(router.query.hash);
const { data: signer } = useSigner(); const { data: signer } = useSigner();
const { isConnected } = useAccount(); const { isConnected } = useAccount();
const { data, isLoading, isError } = useApiQuery(isProxy ? 'contract_methods_write_proxy' : 'contract_methods_write', { const { data, isLoading, isError } = useApiQuery(isProxy ? 'contract_methods_write_proxy' : 'contract_methods_write', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
queryParams: { queryParams: {
is_custom_abi: isCustomAbi ? 'true' : 'false', is_custom_abi: isCustomAbi ? 'true' : 'false',
}, },
......
...@@ -28,9 +28,9 @@ export function ContractContextProvider({ children }: ProviderProps) { ...@@ -28,9 +28,9 @@ export function ContractContextProvider({ children }: ProviderProps) {
const { data: signer } = useSigner(); const { data: signer } = useSigner();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const addressHash = router.query.id?.toString(); const addressHash = router.query.hash?.toString();
const { data: contractInfo } = useApiQuery('contract', { const { data: contractInfo } = useApiQuery('contract', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
queryOptions: { queryOptions: {
enabled: Boolean(addressHash), enabled: Boolean(addressHash),
refetchOnMount: false, refetchOnMount: false,
...@@ -38,11 +38,11 @@ export function ContractContextProvider({ children }: ProviderProps) { ...@@ -38,11 +38,11 @@ export function ContractContextProvider({ children }: ProviderProps) {
}); });
const addressInfo = queryClient.getQueryData<Address>(getResourceKey('address', { const addressInfo = queryClient.getQueryData<Address>(getResourceKey('address', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
})); }));
const { data: proxyInfo } = useApiQuery('contract', { const { data: proxyInfo } = useApiQuery('contract', {
pathParams: { id: addressInfo?.implementation_address || '' }, pathParams: { hash: addressInfo?.implementation_address || '' },
queryOptions: { queryOptions: {
enabled: Boolean(addressInfo?.implementation_address), enabled: Boolean(addressInfo?.implementation_address),
refetchOnMount: false, refetchOnMount: false,
......
...@@ -26,7 +26,7 @@ const AddressBalance = ({ data }: Props) => { ...@@ -26,7 +26,7 @@ const AddressBalance = ({ data }: Props) => {
} }
setLastBlockNumber(blockNumber); setLastBlockNumber(blockNumber);
const queryKey = getResourceKey('address', { pathParams: { id: data.hash } }); const queryKey = getResourceKey('address', { pathParams: { hash: data.hash } });
queryClient.setQueryData(queryKey, (prevData: Address | undefined) => { queryClient.setQueryData(queryKey, (prevData: Address | undefined) => {
if (!prevData) { if (!prevData) {
return; return;
......
import { Skeleton } from '@chakra-ui/react'; import { Skeleton } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query'; import type { UseQueryResult } from '@tanstack/react-query';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import type { AddressCounters } from 'types/api/address'; import type { AddressCounters } from 'types/api/address';
import link from 'lib/link/link';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
interface Props { interface Props {
...@@ -42,7 +42,7 @@ const AddressCounterItem = ({ prop, query, address, onClick }: Props) => { ...@@ -42,7 +42,7 @@ const AddressCounterItem = ({ prop, query, address, onClick }: Props) => {
return <span>0</span>; return <span>0</span>;
} }
return ( return (
<LinkInternal href={ link('address_index', { id: address }, { tab: PROP_TO_TAB[prop] }) } onClick={ onClick }> <LinkInternal href={ route({ pathname: '/address/[hash]', query: { hash: address, tab: PROP_TO_TAB[prop] } }) } onClick={ onClick }>
{ Number(data).toLocaleString() } { Number(data).toLocaleString() }
</LinkInternal> </LinkInternal>
); );
......
...@@ -41,10 +41,10 @@ const AddressFavoriteButton = ({ className, hash, isAdded }: Props) => { ...@@ -41,10 +41,10 @@ const AddressFavoriteButton = ({ className, hash, isAdded }: Props) => {
}, [ addModalProps, deleteModalProps, isAdded, isAuth, loginUrl ]); }, [ addModalProps, deleteModalProps, isAdded, isAuth, loginUrl ]);
const handleAddOrDeleteSuccess = React.useCallback(async() => { const handleAddOrDeleteSuccess = React.useCallback(async() => {
const queryKey = getResourceKey('address', { pathParams: { id: router.query.id?.toString() } }); const queryKey = getResourceKey('address', { pathParams: { hash: router.query.hash?.toString() } });
await queryClient.refetchQueries({ queryKey }); await queryClient.refetchQueries({ queryKey });
addModalProps.onClose(); addModalProps.onClose();
}, [ addModalProps, queryClient, router.query.id ]); }, [ addModalProps, queryClient, router.query.hash ]);
const handleAddModalClose = React.useCallback(() => { const handleAddModalClose = React.useCallback(() => {
addModalProps.onClose(); addModalProps.onClose();
......
...@@ -7,8 +7,8 @@ const MockAddressPage = ({ children }: { children: JSX.Element }): JSX.Element = ...@@ -7,8 +7,8 @@ const MockAddressPage = ({ children }: { children: JSX.Element }): JSX.Element =
const router = useRouter(); const router = useRouter();
const { data } = useApiQuery('address', { const { data } = useApiQuery('address', {
pathParams: { id: router.query.id?.toString() }, pathParams: { hash: router.query.hash?.toString() },
queryOptions: { enabled: Boolean(router.query.id) }, queryOptions: { enabled: Boolean(router.query.hash) },
}); });
if (!data) { if (!data) {
......
...@@ -12,13 +12,13 @@ import MockAddressPage from 'ui/address/testUtils/MockAddressPage'; ...@@ -12,13 +12,13 @@ import MockAddressPage from 'ui/address/testUtils/MockAddressPage';
import TokenSelect from './TokenSelect'; import TokenSelect from './TokenSelect';
const ASSET_URL = 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/poa/assets/0xb2a90505dc6680a7a695f7975d0d32EeF610f456/logo.png'; const ASSET_URL = 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/poa/assets/0xb2a90505dc6680a7a695f7975d0d32EeF610f456/logo.png';
const TOKENS_ERC20_API_URL = buildApiUrl('address_tokens', { id: '1' }) + '?type=ERC-20'; const TOKENS_ERC20_API_URL = buildApiUrl('address_tokens', { hash: '1' }) + '?type=ERC-20';
const TOKENS_ERC721_API_URL = buildApiUrl('address_tokens', { id: '1' }) + '?type=ERC-721'; const TOKENS_ERC721_API_URL = buildApiUrl('address_tokens', { hash: '1' }) + '?type=ERC-721';
const TOKENS_ER1155_API_URL = buildApiUrl('address_tokens', { id: '1' }) + '?type=ERC-1155'; const TOKENS_ER1155_API_URL = buildApiUrl('address_tokens', { hash: '1' }) + '?type=ERC-1155';
const ADDRESS_API_URL = buildApiUrl('address', { id: '1' }); const ADDRESS_API_URL = buildApiUrl('address', { id: '1' });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { id: '1' }, query: { hash: '1' },
}, },
}; };
const CLIPPING_AREA = { x: 0, y: 0, width: 360, height: 500 }; const CLIPPING_AREA = { x: 0, y: 0, width: 360, height: 500 };
......
...@@ -11,6 +11,7 @@ import type { Address } from 'types/api/address'; ...@@ -11,6 +11,7 @@ import type { Address } from 'types/api/address';
import walletIcon from 'icons/wallet.svg'; import walletIcon from 'icons/wallet.svg';
import { getResourceKey } from 'lib/api/useApiQuery'; import { getResourceKey } from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
...@@ -28,13 +29,13 @@ const TokenSelect = ({ onClick }: Props) => { ...@@ -28,13 +29,13 @@ const TokenSelect = ({ onClick }: Props) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const [ blockNumber, setBlockNumber ] = React.useState<number>(); const [ blockNumber, setBlockNumber ] = React.useState<number>();
const addressHash = router.query.id?.toString(); const addressHash = getQueryParamString(router.query.hash);
const addressResourceKey = getResourceKey('address', { pathParams: { id: addressHash } }); const addressResourceKey = getResourceKey('address', { pathParams: { hash: addressHash } });
const addressQueryData = queryClient.getQueryData<Address>(addressResourceKey); const addressQueryData = queryClient.getQueryData<Address>(addressResourceKey);
const { data, isError, isLoading, refetch } = useFetchTokens({ hash: addressQueryData?.hash }); const { data, isError, isLoading, refetch } = useFetchTokens({ hash: addressQueryData?.hash });
const tokensResourceKey = getResourceKey('address_tokens', { pathParams: { id: addressQueryData?.hash }, queryParams: { type: 'ERC-20' } }); const tokensResourceKey = getResourceKey('address_tokens', { pathParams: { hash: addressQueryData?.hash }, queryParams: { type: 'ERC-20' } });
const tokensIsFetching = useIsFetching({ queryKey: tokensResourceKey }); const tokensIsFetching = useIsFetching({ queryKey: tokensResourceKey });
const handleTokenBalanceMessage: SocketMessage.AddressTokenBalance['handler'] = React.useCallback((payload) => { const handleTokenBalanceMessage: SocketMessage.AddressTokenBalance['handler'] = React.useCallback((payload) => {
...@@ -82,7 +83,7 @@ const TokenSelect = ({ onClick }: Props) => { ...@@ -82,7 +83,7 @@ const TokenSelect = ({ onClick }: Props) => {
} }
<Tooltip label="Show all tokens"> <Tooltip label="Show all tokens">
<Box> <Box>
<NextLink href={{ pathname: '/address/[id]', query: { id: addressHash || '', tab: 'tokens' } }} passHref> <NextLink href={{ pathname: '/address/[hash]', query: { hash: addressHash, tab: 'tokens' } }} passHref>
<IconButton <IconButton
aria-label="Show all tokens" aria-label="Show all tokens"
variant="outline" variant="outline"
......
...@@ -15,10 +15,10 @@ import TokenBalancesItem from './TokenBalancesItem'; ...@@ -15,10 +15,10 @@ import TokenBalancesItem from './TokenBalancesItem';
const TokenBalances = () => { const TokenBalances = () => {
const router = useRouter(); const router = useRouter();
const hash = router.query.id?.toString(); const hash = router.query.hash?.toString();
const addressQuery = useApiQuery('address', { const addressQuery = useApiQuery('address', {
pathParams: { id: hash }, pathParams: { hash },
queryOptions: { enabled: Boolean(hash) }, queryOptions: { enabled: Boolean(hash) },
}); });
......
...@@ -10,17 +10,17 @@ interface Props { ...@@ -10,17 +10,17 @@ interface Props {
export default function useFetchTokens({ hash }: Props) { export default function useFetchTokens({ hash }: Props) {
const erc20query = useApiQuery('address_tokens', { const erc20query = useApiQuery('address_tokens', {
pathParams: { id: hash }, pathParams: { hash },
queryParams: { type: 'ERC-20' }, queryParams: { type: 'ERC-20' },
queryOptions: { enabled: Boolean(hash), refetchOnMount: false }, queryOptions: { enabled: Boolean(hash), refetchOnMount: false },
}); });
const erc721query = useApiQuery('address_tokens', { const erc721query = useApiQuery('address_tokens', {
pathParams: { id: hash }, pathParams: { hash },
queryParams: { type: 'ERC-721' }, queryParams: { type: 'ERC-721' },
queryOptions: { enabled: Boolean(hash), refetchOnMount: false }, queryOptions: { enabled: Boolean(hash), refetchOnMount: false },
}); });
const erc1155query = useApiQuery('address_tokens', { const erc1155query = useApiQuery('address_tokens', {
pathParams: { id: hash }, pathParams: { hash },
queryParams: { type: 'ERC-1155' }, queryParams: { type: 'ERC-1155' },
queryOptions: { enabled: Boolean(hash), refetchOnMount: false }, queryOptions: { enabled: Boolean(hash), refetchOnMount: false },
}); });
......
...@@ -56,7 +56,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro ...@@ -56,7 +56,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
try { try {
await apiFetch('contract_verification_via', { await apiFetch('contract_verification_via', {
pathParams: { method: data.method, id: hash }, pathParams: { method: data.method, hash },
fetchParams: { fetchParams: {
method: 'POST', method: 'POST',
body, body,
...@@ -87,7 +87,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro ...@@ -87,7 +87,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
variant: 'subtle', variant: 'subtle',
isClosable: true, isClosable: true,
onCloseComplete: () => { onCloseComplete: () => {
router.push({ pathname: '/address/[id]', query: { id: hash, tab: 'contract' } }, undefined, { shallow: true }); router.push({ pathname: '/address/[hash]', query: { hash, tab: 'contract' } }, undefined, { shallow: true });
}, },
}); });
}, [ hash, router, setError, toast ]); }, [ hash, router, setError, toast ]);
......
...@@ -9,6 +9,7 @@ import iconSuccess from 'icons/status/success.svg'; ...@@ -9,6 +9,7 @@ import iconSuccess from 'icons/status/success.svg';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext'; import { useAppContext } from 'lib/appContext';
import notEmpty from 'lib/notEmpty'; import notEmpty from 'lib/notEmpty';
import getQueryParamString from 'lib/router/getQueryParamString';
import AddressBlocksValidated from 'ui/address/AddressBlocksValidated'; import AddressBlocksValidated from 'ui/address/AddressBlocksValidated';
import AddressCoinBalance from 'ui/address/AddressCoinBalance'; import AddressCoinBalance from 'ui/address/AddressCoinBalance';
import AddressContract from 'ui/address/AddressContract'; import AddressContract from 'ui/address/AddressContract';
...@@ -44,10 +45,11 @@ const AddressPageContent = () => { ...@@ -44,10 +45,11 @@ const AddressPageContent = () => {
const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/accounts'); const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/accounts');
const tabsScrollRef = React.useRef<HTMLDivElement>(null); const tabsScrollRef = React.useRef<HTMLDivElement>(null);
const hash = getQueryParamString(router.query.hash);
const addressQuery = useApiQuery('address', { const addressQuery = useApiQuery('address', {
pathParams: { id: router.query.id?.toString() }, pathParams: { hash },
queryOptions: { enabled: Boolean(router.query.id) }, queryOptions: { enabled: Boolean(hash) },
}); });
const tags = [ const tags = [
......
...@@ -26,11 +26,11 @@ const ContractVerification = () => { ...@@ -26,11 +26,11 @@ const ContractVerification = () => {
const hasGoBackLink = referrer && referrer.includes('/address'); const hasGoBackLink = referrer && referrer.includes('/address');
const router = useRouter(); const router = useRouter();
const hash = getQueryParamString(router.query.id); const hash = getQueryParamString(router.query.hash);
const method = getQueryParamString(router.query.method) as SmartContractVerificationMethod; const method = getQueryParamString(router.query.method) as SmartContractVerificationMethod;
const contractQuery = useApiQuery('contract', { const contractQuery = useApiQuery('contract', {
pathParams: { id: hash }, pathParams: { hash },
queryOptions: { queryOptions: {
enabled: Boolean(hash), enabled: Boolean(hash),
}, },
...@@ -55,7 +55,7 @@ const ContractVerification = () => { ...@@ -55,7 +55,7 @@ const ContractVerification = () => {
React.useEffect(() => { React.useEffect(() => {
if (method && hash) { if (method && hash) {
router.replace({ pathname: '/address/[id]/contract_verification', query: { id: hash } }, undefined, { scroll: false, shallow: true }); router.replace({ pathname: '/address/[hash]/contract_verification', query: { hash } }, undefined, { scroll: false, shallow: true });
} }
// onMount only // onMount only
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
...@@ -65,7 +65,7 @@ const ContractVerification = () => { ...@@ -65,7 +65,7 @@ const ContractVerification = () => {
React.useEffect(() => { React.useEffect(() => {
if (isVerifiedContract) { if (isVerifiedContract) {
router.push({ pathname: '/address/[id]', query: { id: hash, tab: 'contract' } }, undefined, { scroll: false, shallow: true }); router.push({ pathname: '/address/[hash]', query: { hash, tab: 'contract' } }, undefined, { scroll: false, shallow: true });
} }
}, [ hash, isVerifiedContract, router ]); }, [ hash, isVerifiedContract, router ]);
......
...@@ -27,7 +27,7 @@ const MarketplaceApp = ({ app, isLoading }: Props) => { ...@@ -27,7 +27,7 @@ const MarketplaceApp = ({ app, isLoading }: Props) => {
const message = { const message = {
blockscoutColorMode: colorMode, blockscoutColorMode: colorMode,
blockscoutRootUrl: appConfig.baseUrl + route({ pathname: '/' }), blockscoutRootUrl: appConfig.baseUrl + route({ pathname: '/' }),
blockscoutAddressExplorerUrl: appConfig.baseUrl + route({ pathname: '/address/[id]', query: { id: '' } }), blockscoutAddressExplorerUrl: appConfig.baseUrl + route({ pathname: '/address/[hash]', query: { hash: '' } }),
blockscoutTransactionExplorerUrl: appConfig.baseUrl + route({ pathname: '/tx/[hash]', query: { hash: '' } }), blockscoutTransactionExplorerUrl: appConfig.baseUrl + route({ pathname: '/tx/[hash]', query: { hash: '' } }),
blockscoutNetworkName: appConfig.network.name, blockscoutNetworkName: appConfig.network.name,
blockscoutNetworkId: Number(appConfig.network.id), blockscoutNetworkId: Number(appConfig.network.id),
......
...@@ -12,7 +12,7 @@ import Token from './Token'; ...@@ -12,7 +12,7 @@ import Token from './Token';
const TOKEN_API_URL = buildApiUrl('token', { hash: '1' }); const TOKEN_API_URL = buildApiUrl('token', { hash: '1' });
const TOKEN_COUNTERS_API_URL = buildApiUrl('token_counters', { hash: '1' }); const TOKEN_COUNTERS_API_URL = buildApiUrl('token_counters', { hash: '1' });
const TOKEN_TRANSFERS_API_URL = buildApiUrl('token_transfers', { hash: '1' }); const TOKEN_TRANSFERS_API_URL = buildApiUrl('token_transfers', { hash: '1' });
const ADDRESS_API_URL = buildApiUrl('address', { id: '1' }); const ADDRESS_API_URL = buildApiUrl('address', { hash: '1' });
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: 1, tab: 'token_transfers' }, query: { hash: 1, tab: 'token_transfers' },
......
...@@ -7,7 +7,6 @@ import type { SearchResultItem } from 'types/api/search'; ...@@ -7,7 +7,6 @@ import type { SearchResultItem } from 'types/api/search';
import blockIcon from 'icons/block.svg'; import blockIcon from 'icons/block.svg';
import txIcon from 'icons/transactions.svg'; import txIcon from 'icons/transactions.svg';
import highlightText from 'lib/highlightText'; import highlightText from 'lib/highlightText';
import link from 'lib/link/link';
import trimTokenSymbol from 'lib/token/trimTokenSymbol'; import trimTokenSymbol from 'lib/token/trimTokenSymbol';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
...@@ -55,7 +54,12 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => { ...@@ -55,7 +54,12 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<Td fontSize="sm"> <Td fontSize="sm">
<Flex alignItems="center" overflow="hidden"> <Flex alignItems="center" overflow="hidden">
<AddressIcon address={{ hash: data.address, is_contract: data.type === 'contract', implementation_name: null }} mr={ 2 } flexShrink={ 0 }/> <AddressIcon address={{ hash: data.address, is_contract: data.type === 'contract', implementation_name: null }} mr={ 2 } flexShrink={ 0 }/>
<LinkInternal href={ link('address_index', { id: data.address }) } fontWeight={ 700 } overflow="hidden" whiteSpace="nowrap"> <LinkInternal
href={ route({ pathname: '/address/[hash]', query: { hash: data.address } }) }
fontWeight={ 700 }
overflow="hidden"
whiteSpace="nowrap"
>
<Box as={ shouldHighlightHash ? 'mark' : 'span' } display="block"> <Box as={ shouldHighlightHash ? 'mark' : 'span' } display="block">
<HashStringShortenDynamic hash={ data.address }/> <HashStringShortenDynamic hash={ data.address }/>
</Box> </Box>
......
...@@ -4,7 +4,6 @@ import type { HTMLAttributeAnchorTarget } from 'react'; ...@@ -4,7 +4,6 @@ import type { HTMLAttributeAnchorTarget } from 'react';
import React from 'react'; import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import link from 'lib/link/link';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
...@@ -51,9 +50,9 @@ const AddressLink = (props: Props) => { ...@@ -51,9 +50,9 @@ const AddressLink = (props: Props) => {
} else if (type === 'block') { } else if (type === 'block') {
url = route({ pathname: '/block/[height]', query: { height: props.height } }); url = route({ pathname: '/block/[height]', query: { height: props.height } });
} else if (type === 'address_token') { } else if (type === 'address_token') {
url = link('address_index', { id: hash }, { tab: 'token_transfers', token: props.tokenHash, scroll_to_tabs: 'true' }); url = route({ pathname: '/address/[hash]', query: { hash, tab: 'token_transfers', token_hash: props.tokenHash, scroll_to_tabs: 'true' } });
} else { } else {
url = link('address_index', { id: hash }); url = route({ pathname: '/address/[hash]', query: { hash } });
} }
const content = (() => { const content = (() => {
......
import { Text, Grid, GridItem, Tooltip, Button, useColorModeValue, Alert, Link } from '@chakra-ui/react'; import { Text, Grid, GridItem, Tooltip, Button, useColorModeValue, Alert, Link } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import type { Log } from 'types/api/log'; import type { Log } from 'types/api/log';
// import searchIcon from 'icons/search.svg'; // import searchIcon from 'icons/search.svg';
import { space } from 'lib/html-entities'; import { space } from 'lib/html-entities';
import link from 'lib/link/link';
import notEmpty from 'lib/notEmpty'; import notEmpty from 'lib/notEmpty';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
...@@ -47,7 +47,7 @@ const LogItem = ({ address, index, topics, data, decoded, type, tx_hash: txHash ...@@ -47,7 +47,7 @@ const LogItem = ({ address, index, topics, data, decoded, type, tx_hash: txHash
<GridItem colSpan={{ base: 1, lg: 2 }}> <GridItem colSpan={{ base: 1, lg: 2 }}>
<Alert status="warning" display="inline-table" whiteSpace="normal"> <Alert status="warning" display="inline-table" whiteSpace="normal">
To see accurate decoded input data, the contract must be verified.{ space } To see accurate decoded input data, the contract must be verified.{ space }
<Link href={ link('address_contract_verification', { id: address.hash }) }>Verify the contract here</Link> <Link href={ route({ pathname: '/address/[hash]/contract_verification', query: { hash: address.hash } }) }>Verify the contract here</Link>
</Alert> </Alert>
</GridItem> </GridItem>
) } ) }
......
...@@ -7,7 +7,6 @@ import type { SearchResultItem } from 'types/api/search'; ...@@ -7,7 +7,6 @@ import type { SearchResultItem } from 'types/api/search';
import blockIcon from 'icons/block.svg'; import blockIcon from 'icons/block.svg';
import txIcon from 'icons/transactions.svg'; import txIcon from 'icons/transactions.svg';
import highlightText from 'lib/highlightText'; import highlightText from 'lib/highlightText';
import link from 'lib/link/link';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import TokenLogo from 'ui/shared/TokenLogo'; import TokenLogo from 'ui/shared/TokenLogo';
...@@ -27,7 +26,7 @@ const SearchBarSuggestItem = ({ data, isMobile, searchTerm }: Props) => { ...@@ -27,7 +26,7 @@ const SearchBarSuggestItem = ({ data, isMobile, searchTerm }: Props) => {
} }
case 'contract': case 'contract':
case 'address': { case 'address': {
return link('address_index', { id: data.address }); return route({ pathname: '/address/[hash]', query: { hash: data.address } });
} }
case 'transaction': { case 'transaction': {
return route({ pathname: '/tx/[hash]', query: { hash: data.tx_hash } }); return route({ pathname: '/tx/[hash]', query: { hash: data.tx_hash } });
......
...@@ -28,7 +28,7 @@ function composeSources(contract: SmartContract | undefined) { ...@@ -28,7 +28,7 @@ function composeSources(contract: SmartContract | undefined) {
const Sol2UmlDiagram = ({ addressHash }: Props) => { const Sol2UmlDiagram = ({ addressHash }: Props) => {
const contractQuery = useApiQuery<'contract', ResourceError>('contract', { const contractQuery = useApiQuery<'contract', ResourceError>('contract', {
pathParams: { id: addressHash }, pathParams: { hash: addressHash },
queryOptions: { queryOptions: {
enabled: Boolean(addressHash), enabled: Boolean(addressHash),
refetchOnMount: false, refetchOnMount: false,
......
...@@ -16,7 +16,7 @@ const TokenContractInfo = ({ tokenQuery }: Props) => { ...@@ -16,7 +16,7 @@ const TokenContractInfo = ({ tokenQuery }: Props) => {
const router = useRouter(); const router = useRouter();
const contractQuery = useApiQuery('address', { const contractQuery = useApiQuery('address', {
pathParams: { id: router.query.hash?.toString() }, pathParams: { hash: router.query.hash?.toString() },
queryOptions: { enabled: Boolean(router.query.hash) }, queryOptions: { enabled: Boolean(router.query.hash) },
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment