Commit 89dcb1db authored by tom's avatar tom

migration to new API resources schema

parent ed00ebe2
...@@ -9,7 +9,7 @@ import type { ApiResource, ResourceName, ResourcePathParams } from './resources' ...@@ -9,7 +9,7 @@ import type { ApiResource, ResourceName, ResourcePathParams } from './resources'
export default function buildUrl<R extends ResourceName>( export default function buildUrl<R extends ResourceName>(
resourceName: R, resourceName: R,
pathParams?: ResourcePathParams<R>, pathParams?: ResourcePathParams<R>,
queryParams?: Record<string, string | Array<string> | number | null | undefined>, queryParams?: Record<string, string | Array<string> | number | boolean | null | undefined>,
): string { ): string {
const resource: ApiResource = RESOURCES[resourceName]; const resource: ApiResource = RESOURCES[resourceName];
const baseUrl = isNeedProxy() ? config.app.baseUrl : (resource.endpoint || config.api.endpoint); const baseUrl = isNeedProxy() ? config.app.baseUrl : (resource.endpoint || config.api.endpoint);
......
...@@ -36,7 +36,15 @@ import type { ChartMarketResponse, ChartTransactionResponse } from 'types/api/ch ...@@ -36,7 +36,15 @@ import type { ChartMarketResponse, ChartTransactionResponse } from 'types/api/ch
import type { BackendVersionConfig } from 'types/api/configs'; import type { BackendVersionConfig } from 'types/api/configs';
import type { SmartContract, SmartContractReadMethod, SmartContractWriteMethod, SmartContractVerificationConfig, SolidityscanReport } from 'types/api/contract'; import type { SmartContract, SmartContractReadMethod, SmartContractWriteMethod, SmartContractVerificationConfig, SolidityscanReport } from 'types/api/contract';
import type { VerifiedContractsResponse, VerifiedContractsFilters, VerifiedContractsCounters } from 'types/api/contracts'; import type { VerifiedContractsResponse, VerifiedContractsFilters, VerifiedContractsCounters } from 'types/api/contracts';
import type { EnsAddressLookupResponse, EnsDomainDetailed, EnsDomainEventsResponse, EnsDomainLookupResponse } from 'types/api/ens'; import type {
EnsAddressLookupFilters,
EnsAddressLookupResponse,
EnsDomainDetailed,
EnsDomainEventsResponse,
EnsDomainLookupFilters,
EnsDomainLookupResponse,
EnsLookupSorting,
} from 'types/api/ens';
import type { IndexingStatus } from 'types/api/indexingStatus'; import type { IndexingStatus } from 'types/api/indexingStatus';
import type { InternalTransactionsResponse } from 'types/api/internalTransaction'; import type { InternalTransactionsResponse } from 'types/api/internalTransaction';
import type { L2DepositsResponse, L2DepositsItem } from 'types/api/l2Deposits'; import type { L2DepositsResponse, L2DepositsItem } from 'types/api/l2Deposits';
...@@ -182,6 +190,7 @@ export const RESOURCES = { ...@@ -182,6 +190,7 @@ export const RESOURCES = {
pathParams: [ 'chainId' as const ], pathParams: [ 'chainId' as const ],
endpoint: getFeaturePayload(config.features.nameService)?.api.endpoint, endpoint: getFeaturePayload(config.features.nameService)?.api.endpoint,
basePath: getFeaturePayload(config.features.nameService)?.api.basePath, basePath: getFeaturePayload(config.features.nameService)?.api.basePath,
filterFields: [ 'address' as const, 'resolved_to' as const, 'owned_by' as const, 'only_active' as const ],
}, },
domain_info: { domain_info: {
path: '/api/v1/:chainId/domains/:name', path: '/api/v1/:chainId/domains/:name',
...@@ -200,6 +209,7 @@ export const RESOURCES = { ...@@ -200,6 +209,7 @@ export const RESOURCES = {
pathParams: [ 'chainId' as const ], pathParams: [ 'chainId' as const ],
endpoint: getFeaturePayload(config.features.nameService)?.api.endpoint, endpoint: getFeaturePayload(config.features.nameService)?.api.endpoint,
basePath: getFeaturePayload(config.features.nameService)?.api.basePath, basePath: getFeaturePayload(config.features.nameService)?.api.basePath,
filterFields: [ 'name' as const, 'only_active' as const ],
}, },
// VISUALIZATION // VISUALIZATION
...@@ -636,7 +646,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | ...@@ -636,7 +646,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' |
'zkevm_l2_txn_batches' | 'zkevm_l2_txn_batch_txs' | 'zkevm_l2_txn_batches' | 'zkevm_l2_txn_batch_txs' |
'withdrawals' | 'address_withdrawals' | 'block_withdrawals' | 'withdrawals' | 'address_withdrawals' | 'block_withdrawals' |
'watchlist' | 'private_tags_address' | 'private_tags_tx' | 'watchlist' | 'private_tags_address' | 'private_tags_tx' |
'domain_events' | 'domains_lookup' | 'addresses_lookup'; 'domains_lookup' | 'addresses_lookup';
export type PaginatedResponse<Q extends PaginatedResources> = ResourcePayload<Q>; export type PaginatedResponse<Q extends PaginatedResources> = ResourcePayload<Q>;
...@@ -757,6 +767,8 @@ Q extends 'token_inventory' ? TokenInventoryFilters : ...@@ -757,6 +767,8 @@ Q extends 'token_inventory' ? TokenInventoryFilters :
Q extends 'tokens' ? TokensFilters : Q extends 'tokens' ? TokensFilters :
Q extends 'tokens_bridged' ? TokensBridgedFilters : Q extends 'tokens_bridged' ? TokensBridgedFilters :
Q extends 'verified_contracts' ? VerifiedContractsFilters : Q extends 'verified_contracts' ? VerifiedContractsFilters :
Q extends 'addresses_lookup' ? EnsAddressLookupFilters :
Q extends 'domains_lookup' ? EnsDomainLookupFilters :
never; never;
/* eslint-enable @typescript-eslint/indent */ /* eslint-enable @typescript-eslint/indent */
...@@ -766,5 +778,7 @@ Q extends 'tokens' ? TokensSorting : ...@@ -766,5 +778,7 @@ Q extends 'tokens' ? TokensSorting :
Q extends 'tokens_bridged' ? TokensSorting : Q extends 'tokens_bridged' ? TokensSorting :
Q extends 'verified_contracts' ? VerifiedContractsSorting : Q extends 'verified_contracts' ? VerifiedContractsSorting :
Q extends 'address_txs' ? TransactionsSorting : Q extends 'address_txs' ? TransactionsSorting :
Q extends 'addresses_lookup' ? EnsLookupSorting :
Q extends 'domains_lookup' ? EnsLookupSorting :
never; never;
/* eslint-enable @typescript-eslint/indent */ /* eslint-enable @typescript-eslint/indent */
...@@ -18,7 +18,7 @@ import type { ApiResource, ResourceName, ResourcePathParams } from './resources' ...@@ -18,7 +18,7 @@ import type { ApiResource, ResourceName, ResourcePathParams } from './resources'
export interface Params<R extends ResourceName> { export interface Params<R extends ResourceName> {
pathParams?: ResourcePathParams<R>; pathParams?: ResourcePathParams<R>;
queryParams?: Record<string, string | Array<string> | number | undefined>; queryParams?: Record<string, string | Array<string> | number | boolean | undefined>;
fetchParams?: Pick<FetchParams, 'body' | 'method' | 'signal'>; fetchParams?: Pick<FetchParams, 'body' | 'method' | 'signal'>;
} }
......
...@@ -2,20 +2,20 @@ import type { EnsDomainDetailed } from 'types/api/ens'; ...@@ -2,20 +2,20 @@ import type { EnsDomainDetailed } from 'types/api/ens';
export const ensDomainA: EnsDomainDetailed = { export const ensDomainA: EnsDomainDetailed = {
id: '0xb140bf9645e54f02ed3c1bcc225566b515a98d1688f10494a5c3bc5b447936a7', id: '0xb140bf9645e54f02ed3c1bcc225566b515a98d1688f10494a5c3bc5b447936a7',
tokenId: '0xf9b76a83152e20da7e5e671de7d79c7de1a2e63add2796aa187bbf98dd2471a6', token_id: '0xf9b76a83152e20da7e5e671de7d79c7de1a2e63add2796aa187bbf98dd2471a6',
name: 'cat.eth', name: 'cat.eth',
registrant: { registrant: {
hash: '0x114d4603199df73e7d157787f8778e21fcd13066', hash: '0x114d4603199df73e7d157787f8778e21fcd13066',
}, },
resolvedAddress: { resolved_address: {
hash: '0xfe6ab8a0dafe7d41adf247c210451c264155c9b0', hash: '0xfe6ab8a0dafe7d41adf247c210451c264155c9b0',
}, },
owner: { owner: {
hash: '0x114d4603199df73e7d157787f8778e21fcd13066', hash: '0x114d4603199df73e7d157787f8778e21fcd13066',
}, },
registrationDate: '2021-06-27T13:34:44.000Z', registration_date: '2021-06-27T13:34:44.000Z',
expiryDate: '2025-03-01T14:20:24.000Z', expiry_date: '2025-03-01T14:20:24.000Z',
otherAddresses: { other_addresses: {
ETH: 'fe6ab8a0dafe7d41adf247c210451c264155c9b0', ETH: 'fe6ab8a0dafe7d41adf247c210451c264155c9b0',
GNO: 'DDAfbb505ad214D7b80b1f830fcCc89B60fb7A83', GNO: 'DDAfbb505ad214D7b80b1f830fcCc89B60fb7A83',
NEAR: 'a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.factory.bridge.near', NEAR: 'a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.factory.bridge.near',
...@@ -24,50 +24,50 @@ export const ensDomainA: EnsDomainDetailed = { ...@@ -24,50 +24,50 @@ export const ensDomainA: EnsDomainDetailed = {
export const ensDomainB: EnsDomainDetailed = { export const ensDomainB: EnsDomainDetailed = {
id: '0x632ac7bec8e883416b371b36beaa822f4784208c99d063ee030020e2bd09b885', id: '0x632ac7bec8e883416b371b36beaa822f4784208c99d063ee030020e2bd09b885',
tokenId: '0xf9b76a83152e20da7e5e671de7d79c7de1a2e63add2796aa187bbf98dd2471a7', token_id: '0xf9b76a83152e20da7e5e671de7d79c7de1a2e63add2796aa187bbf98dd2471a7',
name: 'kitty.kitty.kitty.cat.eth', name: 'kitty.kitty.kitty.cat.eth',
resolvedAddress: null, resolved_address: null,
registrant: { registrant: {
hash: '0x114d4603199df73e7d157787f8778e21fcd13066', hash: '0x114d4603199df73e7d157787f8778e21fcd13066',
}, },
owner: { owner: {
hash: '0x114d4603199df73e7d157787f8778e21fcd13066', hash: '0x114d4603199df73e7d157787f8778e21fcd13066',
}, },
registrationDate: '2023-08-13T13:01:12.000Z', registration_date: '2023-08-13T13:01:12.000Z',
expiryDate: null, expiry_date: null,
otherAddresses: {}, other_addresses: {},
}; };
export const ensDomainC: EnsDomainDetailed = { export const ensDomainC: EnsDomainDetailed = {
id: '0xdb7f351de6d93bda077a9211bdc49f249326d87932e4787d109b0262e9d189ad', id: '0xdb7f351de6d93bda077a9211bdc49f249326d87932e4787d109b0262e9d189ad',
tokenId: '0xf9b76a83152e20da7e5e671de7d79c7de1a2e63add2796aa187bbf98dd2471a8', token_id: '0xf9b76a83152e20da7e5e671de7d79c7de1a2e63add2796aa187bbf98dd2471a8',
name: 'duck.duck.eth', name: 'duck.duck.eth',
registrant: { registrant: {
hash: '0x114d4603199df73e7d157787f8778e21fcd13066', hash: '0x114d4603199df73e7d157787f8778e21fcd13066',
}, },
resolvedAddress: { resolved_address: {
hash: '0xfe6ab8a0dafe7d41adf247c210451c264155c9b0', hash: '0xfe6ab8a0dafe7d41adf247c210451c264155c9b0',
}, },
owner: { owner: {
hash: '0x114d4603199df73e7d157787f8778e21fcd13066', hash: '0x114d4603199df73e7d157787f8778e21fcd13066',
}, },
registrationDate: '2022-04-24T07:34:44.000Z', registration_date: '2022-04-24T07:34:44.000Z',
expiryDate: '2022-11-01T13:10:36.000Z', expiry_date: '2022-11-01T13:10:36.000Z',
otherAddresses: {}, other_addresses: {},
}; };
export const ensDomainD: EnsDomainDetailed = { export const ensDomainD: EnsDomainDetailed = {
id: '0xdb7f351de6d93bda077a9211bdc49f249326d87932e4787d109b0262e9d189ae', id: '0xdb7f351de6d93bda077a9211bdc49f249326d87932e4787d109b0262e9d189ae',
tokenId: '0xf9b76a83152e20da7e5e671de7d79c7de1a2e63add2796aa187bbf98dd2471a9', token_id: '0xf9b76a83152e20da7e5e671de7d79c7de1a2e63add2796aa187bbf98dd2471a9',
name: '🦆.duck.eth', name: '🦆.duck.eth',
registrant: { registrant: {
hash: '0x114d4603199df73e7d157787f8778e21fcd13066', hash: '0x114d4603199df73e7d157787f8778e21fcd13066',
}, },
resolvedAddress: { resolved_address: {
hash: '0x114d4603199df73e7d157787f8778e21fcd13066', hash: '0x114d4603199df73e7d157787f8778e21fcd13066',
}, },
owner: null, owner: null,
registrationDate: '2022-04-24T07:34:44.000Z', registration_date: '2022-04-24T07:34:44.000Z',
expiryDate: '2027-09-23T13:10:36.000Z', expiry_date: '2027-09-23T13:10:36.000Z',
otherAddresses: {}, other_addresses: {},
}; };
import type { EnsDomainEvent } from 'types/api/ens'; import type { EnsDomainEvent } from 'types/api/ens';
export const ensDomainEventA: EnsDomainEvent = { export const ensDomainEventA: EnsDomainEvent = {
transactionHash: '0x86c66b9fad66e4f20d42a6eed4fe12a0f48a274786fd85e9d4aa6c60e84b5874', transaction_hash: '0x86c66b9fad66e4f20d42a6eed4fe12a0f48a274786fd85e9d4aa6c60e84b5874',
timestamp: '2021-06-27T13:34:44.000000Z', timestamp: '2021-06-27T13:34:44.000000Z',
fromAddress: { from_address: {
hash: '0xaa96a50a2f67111262fe24576bd85bb56ec65016', hash: '0xaa96a50a2f67111262fe24576bd85bb56ec65016',
}, },
action: '0xf7a16963', action: '0xf7a16963',
}; };
export const ensDomainEventB = { export const ensDomainEventB = {
transactionHash: '0x150bf7d5cd42457dd9c799ddd9d4bf6c30c703e1954a88c6d4b668b23fe0fbf8', transaction_hash: '0x150bf7d5cd42457dd9c799ddd9d4bf6c30c703e1954a88c6d4b668b23fe0fbf8',
timestamp: '2022-11-02T14:20:24.000000Z', timestamp: '2022-11-02T14:20:24.000000Z',
fromAddress: { from_address: {
hash: '0xfe6ab8a0dafe7d41adf247c210451c264155c9b0', hash: '0xfe6ab8a0dafe7d41adf247c210451c264155c9b0',
}, },
action: 'register', action: 'register',
......
import type { EnsDomainDetailed } from 'types/api/ens'; import type { EnsDomainDetailed, EnsDomainEvent } from 'types/api/ens';
import { ADDRESS_PARAMS, ADDRESS_HASH } from './addressParams'; import { ADDRESS_PARAMS, ADDRESS_HASH } from './addressParams';
import { TX_HASH } from './tx'; import { TX_HASH } from './tx';
...@@ -6,20 +6,20 @@ import { TX_HASH } from './tx'; ...@@ -6,20 +6,20 @@ import { TX_HASH } from './tx';
export const ENS_DOMAIN: EnsDomainDetailed = { export const ENS_DOMAIN: EnsDomainDetailed = {
id: '0x126d74db13895f8d3a1d362410212731d1e1d9be8add83e388385f93d84c8c84', id: '0x126d74db13895f8d3a1d362410212731d1e1d9be8add83e388385f93d84c8c84',
name: 'kitty.cat.eth', name: 'kitty.cat.eth',
tokenId: '0x686f4041f059de13c12563c94bd32b8edef9e4d86c931f37abb8cb69ecf25fd6', token_id: '0x686f4041f059de13c12563c94bd32b8edef9e4d86c931f37abb8cb69ecf25fd6',
owner: ADDRESS_PARAMS, owner: ADDRESS_PARAMS,
resolvedAddress: ADDRESS_PARAMS, resolved_address: ADDRESS_PARAMS,
registrant: ADDRESS_PARAMS, registrant: ADDRESS_PARAMS,
registrationDate: '2023-12-20T01:29:12.000Z', registration_date: '2023-12-20T01:29:12.000Z',
expiryDate: '2099-01-02T01:29:12.000Z', expiry_date: '2099-01-02T01:29:12.000Z',
otherAddresses: { other_addresses: {
ETH: ADDRESS_HASH, ETH: ADDRESS_HASH,
}, },
}; };
export const ENS_DOMAIN_EVENT = { export const ENS_DOMAIN_EVENT: EnsDomainEvent = {
transactionHash: TX_HASH, transaction_hash: TX_HASH,
timestamp: '2022-06-06T08:43:15.000000Z', timestamp: '2022-06-06T08:43:15.000000Z',
fromAddress: ADDRESS_PARAMS, from_address: ADDRESS_PARAMS,
action: '0xf7a16963', action: '0xf7a16963',
}; };
export interface EnsDomain { export interface EnsDomain {
id: string; id: string;
name: string; name: string;
resolvedAddress: { resolved_address: {
hash: string; hash: string;
} | null; } | null;
owner: { owner: {
hash: string; hash: string;
} | null; } | null;
registrationDate?: string; registration_date?: string;
expiryDate: string | null; expiry_date: string | null;
} }
export interface EnsDomainDetailed extends EnsDomain { export interface EnsDomainDetailed extends EnsDomain {
tokenId: string; token_id: string;
registrant: { registrant: {
hash: string; hash: string;
} | null; } | null;
otherAddresses: Record<string, string>; other_addresses: Record<string, string>;
} }
export interface EnsDomainEvent { export interface EnsDomainEvent {
transactionHash: string; transaction_hash: string;
timestamp: string; timestamp: string;
fromAddress: { from_address: {
hash: string; hash: string;
} | null; } | null;
action?: string; action?: string;
...@@ -30,24 +30,39 @@ export interface EnsDomainEvent { ...@@ -30,24 +30,39 @@ export interface EnsDomainEvent {
export interface EnsAddressLookupResponse { export interface EnsAddressLookupResponse {
items: Array<EnsDomain>; items: Array<EnsDomain>;
totalRecords: number; next_page_params: {
page_token: string;
page_size: number;
} | null;
} }
export interface EnsDomainEventsResponse { export interface EnsDomainEventsResponse {
items: Array<EnsDomainEvent>; items: Array<EnsDomainEvent>;
totalRecords: number;
} }
export interface EnsDomainLookupResponse { export interface EnsDomainLookupResponse {
items: Array<EnsDomain>; items: Array<EnsDomain>;
totalRecords: number; next_page_params: {
page_token: string;
page_size: number;
} | null;
}
export interface EnsAddressLookupFilters {
address: string | null;
resolved_to: boolean;
owned_by: boolean;
only_active: boolean;
} }
export interface EnsDomainLookupFilters { export interface EnsDomainLookupFilters {
name: string | null; name: string | null;
resolvedTo: boolean; only_active: boolean;
ownedBy: boolean; }
onlyActive: boolean;
export interface EnsLookupSorting {
sort: 'registration_date';
order: 'ASC' | 'DESC';
} }
export type EnsDomainLookupFiltersOptions = Array<'resolvedTo' | 'ownedBy' | 'withInactive'>; export type EnsDomainLookupFiltersOptions = Array<'resolved_to' | 'owned_by' | 'with_inactive'>;
import { Button, chakra, Flex, Grid, Icon, Popover, PopoverBody, PopoverContent, PopoverTrigger, Skeleton, useDisclosure } from '@chakra-ui/react'; import { Button, chakra, Flex, Grid, Popover, PopoverBody, PopoverContent, PopoverTrigger, Skeleton, useDisclosure } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import arrowIcon from 'icons/arrows/east-mini.svg';
import ensIcon from 'icons/ENS_slim.svg';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import EnsEntity from 'ui/shared/entities/ens/EnsEntity'; import EnsEntity from 'ui/shared/entities/ens/EnsEntity';
import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
interface Props { interface Props {
...@@ -21,14 +20,12 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => { ...@@ -21,14 +20,12 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => {
const { data, isPending, isError } = useApiQuery('addresses_lookup', { const { data, isPending, isError } = useApiQuery('addresses_lookup', {
pathParams: { chainId: config.chain.id }, pathParams: { chainId: config.chain.id },
fetchParams: { queryParams: {
method: 'POST', address: addressHash,
body: { resolved_to: true,
address: addressHash, owned_by: true,
resolvedTo: true, only_active: true,
ownedBy: true, order: 'ASC',
onlyActive: true,
},
}, },
}); });
...@@ -47,11 +44,13 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => { ...@@ -47,11 +44,13 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => {
domain.name !== mainDomainName, domain.name !== mainDomainName,
); );
const resolvedDomains = data.items.filter((domain) => const resolvedDomains = data.items.filter((domain) =>
domain.resolvedAddress && domain.resolved_address &&
domain.resolvedAddress.hash.toLowerCase() === addressHash.toLowerCase() && domain.resolved_address.hash.toLowerCase() === addressHash.toLowerCase() &&
domain.name !== mainDomainName, domain.name !== mainDomainName,
); );
const totalRecords = data.next_page_params ? '50+' : data.items.length;
return ( return (
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy> <Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy>
<PopoverTrigger> <PopoverTrigger>
...@@ -66,9 +65,9 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => { ...@@ -66,9 +65,9 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => {
h="32px" h="32px"
flexShrink={ 0 } flexShrink={ 0 }
> >
<Icon as={ ensIcon } boxSize={ 5 }/> <IconSvg name="ENS_slim" boxSize={ 5 }/>
<chakra.span ml={ 1 } display={{ base: 'none', lg: 'block' }}>{ data.totalRecords } Domains</chakra.span> <chakra.span ml={ 1 } display={{ base: 'none', lg: 'block' }}>{ totalRecords } Domains</chakra.span>
<Icon as={ arrowIcon } transform={ isOpen ? 'rotate(90deg)' : 'rotate(-90deg)' } transitionDuration="faster" boxSize={ 5 }/> <IconSvg name="arrows/east-mini" transform={ isOpen ? 'rotate(90deg)' : 'rotate(-90deg)' } transitionDuration="faster" boxSize={ 5 }/>
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent w={{ base: '100vw', lg: '500px' }}> <PopoverContent w={{ base: '100vw', lg: '500px' }}>
...@@ -78,8 +77,8 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => { ...@@ -78,8 +77,8 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => {
<p>A domain name is not necessarily held by a person popularly associated with the name.</p> <p>A domain name is not necessarily held by a person popularly associated with the name.</p>
<Flex alignItems="center" fontSize="md" mt={ 4 }> <Flex alignItems="center" fontSize="md" mt={ 4 }>
<EnsEntity name={ mainDomain.name } fontWeight={ 600 } noCopy/> <EnsEntity name={ mainDomain.name } fontWeight={ 600 } noCopy/>
{ mainDomain.expiryDate && { mainDomain.expiry_date &&
<chakra.span color="text_secondary" whiteSpace="pre"> (expires { dayjs(mainDomain.expiryDate).fromNow() })</chakra.span> } <chakra.span color="text_secondary" whiteSpace="pre"> (expires { dayjs(mainDomain.expiry_date).fromNow() })</chakra.span> }
</Flex> </Flex>
</div> </div>
) } ) }
...@@ -101,10 +100,10 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => { ...@@ -101,10 +100,10 @@ const AddressEnsDomains = ({ addressHash, mainDomainName }: Props) => {
) } ) }
{ (ownedDomains.length > 9 || resolvedDomains.length > 9) && ( { (ownedDomains.length > 9 || resolvedDomains.length > 9) && (
<LinkInternal <LinkInternal
href={ route({ pathname: '/name-domains', query: { ownedBy: 'true', resolvedTo: 'true', q: addressHash } }) } href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', q: addressHash } }) }
> >
<span> More results</span> <span> More results</span>
<chakra.span color="text_secondary"> ({ data.totalRecords })</chakra.span> <chakra.span color="text_secondary"> ({ totalRecords })</chakra.span>
</LinkInternal> </LinkInternal>
) } ) }
</PopoverBody> </PopoverBody>
......
...@@ -23,12 +23,12 @@ interface Props { ...@@ -23,12 +23,12 @@ interface Props {
const NameDomainDetails = ({ query }: Props) => { const NameDomainDetails = ({ query }: Props) => {
const isLoading = query.isPlaceholderData; const isLoading = query.isPlaceholderData;
const otherAddresses = Object.entries(query.data?.otherAddresses ?? {}); const otherAddresses = Object.entries(query.data?.other_addresses ?? {});
const hasExpired = query.data?.expiryDate && dayjs(query.data.expiryDate).isBefore(dayjs()); const hasExpired = query.data?.expiry_date && dayjs(query.data.expiry_date).isBefore(dayjs());
return ( return (
<Grid columnGap={ 8 } rowGap={ 3 } templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}> <Grid columnGap={ 8 } rowGap={ 3 } templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}>
{ query.data?.expiryDate && ( { query.data?.expiry_date && (
<DetailsInfoItem <DetailsInfoItem
title="Expiration date" title="Expiration date"
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
...@@ -42,17 +42,17 @@ const NameDomainDetails = ({ query }: Props) => { ...@@ -42,17 +42,17 @@ const NameDomainDetails = ({ query }: Props) => {
{ hasExpired && ( { hasExpired && (
<> <>
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="24px"> <Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="24px">
{ dayjs(query.data.expiryDate).fromNow() } { dayjs(query.data.expiry_date).fromNow() }
</Skeleton> </Skeleton>
<TextSeparator color="gray.500"/> <TextSeparator color="gray.500"/>
</> </>
) } ) }
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="24px"> <Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="24px">
{ dayjs(query.data.expiryDate).format('llll') } { dayjs(query.data.expiry_date).format('llll') }
</Skeleton> </Skeleton>
<TextSeparator color="gray.500"/> <TextSeparator color="gray.500"/>
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline"> <Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline">
<NameDomainExpiryStatus date={ query.data?.expiryDate }/> <NameDomainExpiryStatus date={ query.data?.expiry_date }/>
</Skeleton> </Skeleton>
</DetailsInfoItem> </DetailsInfoItem>
) } ) }
...@@ -72,7 +72,7 @@ const NameDomainDetails = ({ query }: Props) => { ...@@ -72,7 +72,7 @@ const NameDomainDetails = ({ query }: Props) => {
<LinkInternal <LinkInternal
flexShrink={ 0 } flexShrink={ 0 }
display="inline-flex" display="inline-flex"
href={ route({ pathname: '/name-domains', query: { ownedBy: 'true', resolvedTo: 'true', q: query.data.registrant.hash } }) } href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', q: query.data.registrant.hash } }) }
> >
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/> <IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
</LinkInternal> </LinkInternal>
...@@ -95,7 +95,7 @@ const NameDomainDetails = ({ query }: Props) => { ...@@ -95,7 +95,7 @@ const NameDomainDetails = ({ query }: Props) => {
<LinkInternal <LinkInternal
flexShrink={ 0 } flexShrink={ 0 }
display="inline-flex" display="inline-flex"
href={ route({ pathname: '/name-domains', query: { ownedBy: 'true', resolvedTo: 'true', q: query.data.owner.hash } }) } href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', q: query.data.owner.hash } }) }
> >
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/> <IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
</LinkInternal> </LinkInternal>
...@@ -110,7 +110,7 @@ const NameDomainDetails = ({ query }: Props) => { ...@@ -110,7 +110,7 @@ const NameDomainDetails = ({ query }: Props) => {
whiteSpace="pre-wrap" whiteSpace="pre-wrap"
> >
<Skeleton isLoaded={ !isLoading }> <Skeleton isLoaded={ !isLoading }>
{ query.data?.tokenId } { query.data?.token_id }
</Skeleton> </Skeleton>
</DetailsInfoItem> </DetailsInfoItem>
{ otherAddresses.length > 0 && ( { otherAddresses.length > 0 && (
......
...@@ -6,7 +6,6 @@ import config from 'configs/app'; ...@@ -6,7 +6,6 @@ import config from 'configs/app';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import { ENS_DOMAIN_EVENT } from 'stubs/ENS'; import { ENS_DOMAIN_EVENT } from 'stubs/ENS';
import { generateListStub } from 'stubs/utils';
import DataListDisplay from 'ui/shared/DataListDisplay'; import DataListDisplay from 'ui/shared/DataListDisplay';
import NameDomainHistoryListItem from './history/NameDomainHistoryListItem'; import NameDomainHistoryListItem from './history/NameDomainHistoryListItem';
...@@ -22,7 +21,7 @@ const NameDomainHistory = () => { ...@@ -22,7 +21,7 @@ const NameDomainHistory = () => {
const { isPlaceholderData, isError, data } = useApiQuery('domain_events', { const { isPlaceholderData, isError, data } = useApiQuery('domain_events', {
pathParams: { name: domainName, chainId: config.chain.id }, pathParams: { name: domainName, chainId: config.chain.id },
queryOptions: { queryOptions: {
placeholderData: generateListStub<'domain_events'>(ENS_DOMAIN_EVENT, 4, { totalRecords: 4 }), placeholderData: { items: Array(4).fill(ENS_DOMAIN_EVENT) },
}, },
}); });
......
...@@ -13,7 +13,7 @@ type Props = EnsDomainEvent & { ...@@ -13,7 +13,7 @@ type Props = EnsDomainEvent & {
isLoading?: boolean; isLoading?: boolean;
} }
const NameDomainHistoryListItem = ({ isLoading, transactionHash, timestamp, fromAddress, action }: Props) => { const NameDomainHistoryListItem = ({ isLoading, transaction_hash: transactionHash, timestamp, from_address: fromAddress, action }: Props) => {
return ( return (
<ListItemMobileGrid.Container> <ListItemMobileGrid.Container>
<ListItemMobileGrid.Label isLoading={ isLoading }>Txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Txn hash</ListItemMobileGrid.Label>
......
...@@ -12,7 +12,7 @@ type Props = EnsDomainEvent & { ...@@ -12,7 +12,7 @@ type Props = EnsDomainEvent & {
isLoading?: boolean; isLoading?: boolean;
} }
const NameDomainHistoryTableItem = ({ isLoading, transactionHash, fromAddress, action, timestamp }: Props) => { const NameDomainHistoryTableItem = ({ isLoading, transaction_hash: transactionHash, from_address: fromAddress, action, timestamp }: Props) => {
return ( return (
<Tr> <Tr>
......
...@@ -57,11 +57,11 @@ const NameDomainsActionBar = ({ searchTerm, onSearchChange, filterValue, onFilte ...@@ -57,11 +57,11 @@ const NameDomainsActionBar = ({ searchTerm, onSearchChange, filterValue, onFilte
<div> <div>
<CheckboxGroup size="lg" onChange={ onFilterValueChange } value={ filterValue } defaultValue={ filterValue }> <CheckboxGroup size="lg" onChange={ onFilterValueChange } value={ filterValue } defaultValue={ filterValue }>
<Text variant="secondary" fontWeight={ 600 } mb={ 3 } fontSize="sm">Address</Text> <Text variant="secondary" fontWeight={ 600 } mb={ 3 } fontSize="sm">Address</Text>
<Checkbox value="ownedBy" display="block" isDisabled={ !isAddressSearch }> <Checkbox value="owned_by" display="block" isDisabled={ !isAddressSearch }>
Owned by Owned by
</Checkbox> </Checkbox>
<Checkbox <Checkbox
value="resolvedTo" value="resolved_to"
display="block" display="block"
mt={ 5 } mt={ 5 }
mb={ 4 } mb={ 4 }
...@@ -73,7 +73,7 @@ const NameDomainsActionBar = ({ searchTerm, onSearchChange, filterValue, onFilte ...@@ -73,7 +73,7 @@ const NameDomainsActionBar = ({ searchTerm, onSearchChange, filterValue, onFilte
Resolved to address Resolved to address
</Checkbox> </Checkbox>
<Text variant="secondary" fontWeight={ 600 } mb={ 3 } fontSize="sm">Status</Text> <Text variant="secondary" fontWeight={ 600 } mb={ 3 } fontSize="sm">Status</Text>
<Checkbox value="withInactive" display="block"> <Checkbox value="with_inactive" display="block">
Include expired Include expired
</Checkbox> </Checkbox>
</CheckboxGroup> </CheckboxGroup>
......
...@@ -13,7 +13,7 @@ interface Props extends EnsDomain { ...@@ -13,7 +13,7 @@ interface Props extends EnsDomain {
isLoading: boolean; isLoading: boolean;
} }
const NameDomainsListItem = ({ name, isLoading, resolvedAddress, registrationDate, expiryDate }: Props) => { const NameDomainsListItem = ({ name, isLoading, resolved_address: resolvedAddress, registration_date: registrationDate, expiry_date: expiryDate }: Props) => {
return ( return (
<ListItemMobileGrid.Container> <ListItemMobileGrid.Container>
<ListItemMobileGrid.Label isLoading={ isLoading }>Domain</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Domain</ListItemMobileGrid.Label>
......
...@@ -12,7 +12,7 @@ type Props = EnsDomain & { ...@@ -12,7 +12,7 @@ type Props = EnsDomain & {
isLoading?: boolean; isLoading?: boolean;
} }
const NameDomainsTableItem = ({ isLoading, name, resolvedAddress, registrationDate, expiryDate }: Props) => { const NameDomainsTableItem = ({ isLoading, name, resolved_address: resolvedAddress, registration_date: registrationDate, expiry_date: expiryDate }: Props) => {
return ( return (
<Tr> <Tr>
......
import type { EnsLookupSorting } from 'types/api/ens';
import getNextSortValueShared from 'ui/shared/sort/getNextSortValue'; import getNextSortValueShared from 'ui/shared/sort/getNextSortValue';
import type { Option } from 'ui/shared/sort/Sort'; import type { Option } from 'ui/shared/sort/Sort';
export type SortField = 'registration_date'; export type SortField = EnsLookupSorting['sort'];
export type Sort = `${ SortField }-asc` | `${ SortField }-desc`; export type Sort = `${ EnsLookupSorting['sort'] }-${ EnsLookupSorting['order'] }`;
export const SORT_OPTIONS: Array<Option<Sort>> = [ export const SORT_OPTIONS: Array<Option<Sort>> = [
{ title: 'Default', id: undefined }, { title: 'Default', id: undefined },
{ title: 'Registered on descending', id: 'registration_date-desc' }, { title: 'Registered on descending', id: 'registration_date-DESC' },
{ title: 'Registered on ascending', id: 'registration_date-asc' }, { title: 'Registered on ascending', id: 'registration_date-ASC' },
]; ];
const SORT_SEQUENCE: Record<SortField, Array<Sort | undefined>> = { const SORT_SEQUENCE: Record<SortField, Array<Sort | undefined>> = {
registration_date: [ 'registration_date-desc', 'registration_date-asc', undefined ], registration_date: [ 'registration_date-DESC', 'registration_date-ASC', undefined ],
}; };
export const getNextSortValue = (getNextSortValueShared<SortField, Sort>).bind(undefined, SORT_SEQUENCE); export const getNextSortValue = (getNextSortValueShared<SortField, Sort>).bind(undefined, SORT_SEQUENCE);
...@@ -56,21 +56,21 @@ const NameDomain = () => { ...@@ -56,21 +56,21 @@ const NameDomain = () => {
noLink noLink
maxW="300px" maxW="300px"
/> />
{ infoQuery.data?.resolvedAddress && ( { infoQuery.data?.resolved_address && (
<AddressEntity <AddressEntity
address={ infoQuery.data?.resolvedAddress } address={ infoQuery.data?.resolved_address }
isLoading={ isLoading } isLoading={ isLoading }
truncation={ isMobile ? 'constant' : 'dynamic' } truncation={ isMobile ? 'constant' : 'dynamic' }
noLink noLink
flexShrink={ 0 } flexShrink={ 0 }
/> />
) } ) }
{ infoQuery.data?.resolvedAddress && ( { infoQuery.data?.resolved_address && (
<Tooltip label="Lookup for related domain names"> <Tooltip label="Lookup for related domain names">
<LinkInternal <LinkInternal
flexShrink={ 0 } flexShrink={ 0 }
display="inline-flex" display="inline-flex"
href={ route({ pathname: '/name-domains', query: { ownedBy: 'true', resolvedTo: 'true', q: infoQuery.data?.resolvedAddress?.hash } }) } href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', q: infoQuery.data?.resolved_address?.hash } }) }
> >
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/> <IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
</LinkInternal> </LinkInternal>
......
...@@ -24,14 +24,14 @@ const NameDomains = () => { ...@@ -24,14 +24,14 @@ const NameDomains = () => {
const router = useRouter(); const router = useRouter();
const q = getQueryParamString(router.query.q); const q = getQueryParamString(router.query.q);
const ownedBy = getQueryParamString(router.query.ownedBy); const ownedBy = getQueryParamString(router.query.owned_by);
const resolvedTo = getQueryParamString(router.query.resolvedTo); const resolvedTo = getQueryParamString(router.query.resolved_to);
const withInactive = getQueryParamString(router.query.withInactive); const withInactive = getQueryParamString(router.query.with_inactive);
const initialFilters: EnsDomainLookupFiltersOptions = [ const initialFilters: EnsDomainLookupFiltersOptions = [
ownedBy === 'true' ? 'ownedBy' as const : undefined, ownedBy === 'true' ? 'owned_by' as const : undefined,
resolvedTo === 'true' ? 'resolvedTo' as const : undefined, resolvedTo === 'true' ? 'resolved_to' as const : undefined,
withInactive === 'true' ? 'withInactive' as const : undefined, withInactive === 'true' ? 'with_inactive' as const : undefined,
].filter(Boolean); ].filter(Boolean);
const [ searchTerm, setSearchTerm ] = React.useState<string>(q || ''); const [ searchTerm, setSearchTerm ] = React.useState<string>(q || '');
...@@ -41,41 +41,35 @@ const NameDomains = () => { ...@@ -41,41 +41,35 @@ const NameDomains = () => {
const debouncedSearchTerm = useDebounce(searchTerm, 300); const debouncedSearchTerm = useDebounce(searchTerm, 300);
const isAddressSearch = React.useMemo(() => ADDRESS_REGEXP.test(debouncedSearchTerm), [ debouncedSearchTerm ]); const isAddressSearch = React.useMemo(() => ADDRESS_REGEXP.test(debouncedSearchTerm), [ debouncedSearchTerm ]);
const sortParam = sort?.split('-')[0]; const sortParam = sort?.split('-')[0];
const orderParam = sort?.split('-')[1].toUpperCase(); const orderParam = sort?.split('-')[1];
const addressesLookupQuery = useApiQuery('addresses_lookup', { const addressesLookupQuery = useApiQuery('addresses_lookup', {
pathParams: { chainId: config.chain.id }, pathParams: { chainId: config.chain.id },
fetchParams: { queryParams: {
method: 'POST', address: debouncedSearchTerm,
body: { resolved_to: filterValue.includes('resolved_to'),
address: debouncedSearchTerm, owned_by: filterValue.includes('owned_by'),
resolvedTo: filterValue.includes('resolvedTo'), only_active: !filterValue.includes('with_inactive'),
ownedBy: filterValue.includes('ownedBy'), sort: sortParam,
onlyActive: !filterValue.includes('withInactive'), order: orderParam,
sort: sortParam,
order: orderParam,
},
}, },
queryOptions: { queryOptions: {
enabled: isAddressSearch, enabled: isAddressSearch,
placeholderData: generateListStub<'addresses_lookup'>(ENS_DOMAIN, 50, { totalRecords: 50 }), placeholderData: generateListStub<'addresses_lookup'>(ENS_DOMAIN, 50, { next_page_params: null }),
}, },
}); });
const domainsLookupQuery = useApiQuery('domains_lookup', { const domainsLookupQuery = useApiQuery('domains_lookup', {
pathParams: { chainId: config.chain.id }, pathParams: { chainId: config.chain.id },
fetchParams: { queryParams: {
method: 'POST', name: debouncedSearchTerm,
body: { only_active: !filterValue.includes('with_inactive'),
name: debouncedSearchTerm, sort: sortParam,
onlyActive: !filterValue.includes('withInactive'), order: orderParam,
sort: sortParam,
order: orderParam,
},
}, },
queryOptions: { queryOptions: {
enabled: !isAddressSearch, enabled: !isAddressSearch,
placeholderData: generateListStub<'domains_lookup'>(ENS_DOMAIN, 50, { totalRecords: 50 }), placeholderData: generateListStub<'domains_lookup'>(ENS_DOMAIN, 50, { next_page_params: null }),
}, },
}); });
...@@ -83,8 +77,8 @@ const NameDomains = () => { ...@@ -83,8 +77,8 @@ const NameDomains = () => {
const { data, isError, isPlaceholderData: isLoading } = query; const { data, isError, isPlaceholderData: isLoading } = query;
React.useEffect(() => { React.useEffect(() => {
if (isAddressSearch && filterValue.filter((value) => value !== 'withInactive').length === 0) { if (isAddressSearch && filterValue.filter((value) => value !== 'with_inactive').length === 0) {
setFilterValue([ 'ownedBy', 'resolvedTo' ]); setFilterValue([ 'owned_by', 'resolved_to' ]);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [ isAddressSearch ]); }, [ isAddressSearch ]);
......
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