Skip to content

Clusters Feature Integration #2816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 84 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
09aff98
adds clusters api configs
ayv8er Jun 22, 2025
18eeee5
adds clusters api configs
ayv8er Jun 22, 2025
3e8c016
adds api types
ayv8er Jun 22, 2025
073ff24
adds props routes and titles for cluster pages
ayv8er Jun 22, 2025
98c2ac4
adds query param enum for clusters api
ayv8er Jun 22, 2025
ebc3b21
adds clusters svg
ayv8er Jun 22, 2025
416e1ac
adds dynamic page routes
ayv8er Jun 22, 2025
489f650
adds clusters entity ui in ui/shared/entities
ayv8er Jun 22, 2025
3c78b55
adds functions to detect input type; will be used to check whether a …
ayv8er Jun 22, 2025
bcc9f55
adds stubs for loading skeleton view
ayv8er Jun 22, 2025
ba2481a
adds pagination hook
ayv8er Jun 23, 2025
6e82802
adds query param hooks for clusters trpc endpoints
ayv8er Jun 23, 2025
e3176db
adds query param hooks for clusters trpc endpoints
ayv8er Jun 23, 2025
f51fb65
adds components that make up the /clusters ui
ayv8er Jun 23, 2025
7abf89a
adds components for /cluster ui
ayv8er Jun 23, 2025
283ca0a
adds clusters api endpoint to query by cluster id
ayv8er Jun 23, 2025
31d0ae5
implements call to cluster id endpoint to get ac
ayv8er Jun 23, 2025
7603627
adds clusters search types and in api category
ayv8er Jun 23, 2025
0f30607
creates clusters search hook and wraps useQuickSearchQuery hook
ayv8er Jun 23, 2025
c5698ff
replaces useQuickSearchQuery for useSearchWithClusters hook for both …
ayv8er Jun 23, 2025
a2e02f1
add search suggestion ui
ayv8er Jun 23, 2025
b75739b
adds optional chaining to handle react re-render when search type cha…
ayv8er Jun 23, 2025
f50021c
adds cluster ui to ui/pages/address on address details
ayv8er Jun 24, 2025
912538f
prevents clicking on cluster suggestion if address is non EVM
ayv8er Jun 24, 2025
5c66c45
adds util functions for testability along with tests, for action bar …
ayv8er Jun 24, 2025
d74ebe0
refactor - extract clusters display logic wit
ayv8er Jun 24, 2025
370a674
refactor: extract page utilities from Clusters.tsx with tests
ayv8er Jun 24, 2025
9a11dc3
adds jest testing infra for react components
ayv8er Jun 25, 2025
265788d
adds hook testing coverage
ayv8er Jun 25, 2025
5176607
adds component and integration tests
ayv8er Jun 25, 2025
182daae
adds detectInputType util tests
ayv8er Jun 25, 2025
fb4f80a
removes generic parameters from clusters pagination types
ayv8er Jun 25, 2025
1603710
replaces any type with proper cluster config types
ayv8er Jun 25, 2025
aaa02d1
adds cluster routes to metadata and analytics mappings
ayv8er Jun 25, 2025
a21d2fd
updates order and stacks action bar items vertically when mobile view
ayv8er Jun 25, 2025
9888e77
repositions clusters logo
ayv8er Jun 25, 2025
88af76f
refactors search logic to render community clusters in search sugge
ayv8er Jun 25, 2025
75133fc
adding clusters env vars
ayv8er Jun 25, 2025
d37f17d
centers directory/leaderboard toggle in mobile view
ayv8er Jun 25, 2025
057d8e6
resizes and sets proper color to logo in entity component
ayv8er Jun 27, 2025
304766d
hides clusters nav when clusters env is missing
ayv8er Jun 30, 2025
ae4a40e
removes duplicate trailing slashes in cluster community names
ayv8er Jun 30, 2025
cfdba44
merge upstream/main into clusters-page
ayv8er Jun 30, 2025
ba5828a
replaces jest-dom matchers with standard matchers
ayv8er Jul 1, 2025
3f2d7a4
makes /clusters page default view the directory instead of leaderboar…
ayv8er Jul 2, 2025
0e91fe5
updates columnn name from backing to total backing, in leaderboard di…
ayv8er Jul 2, 2025
4e201c0
alphabetically reorders clusters export
ayv8er Jul 2, 2025
4312c3e
adds Cluster section to the Table of Cont
ayv8er Jul 2, 2025
d6ff530
removes redundant Flex component wrapper around ClustersEntity
ayv8er Jul 2, 2025
066e495
uses standard toolkit values for border radius and color
ayv8er Jul 2, 2025
35eaed3
uses getFeaturePayload util instead of type coercion
ayv8er Jul 2, 2025
9bcfc47
extends ImageProps interface to ClusterIconProps, and uses getFeature…
ayv8er Jul 2, 2025
95ae994
adds evm address regexp in regexp.ts as single source of truth
ayv8er Jul 3, 2025
6820d73
updates imports for files that used form validator address regexp to …
ayv8er Jul 3, 2025
059c369
removes unused args, unnecessary type coercions and memoizations. upp…
ayv8er Jul 3, 2025
1afccf2
sets correct action bar height using ACTION_BAR_HEIGHT_DESKTOP constant
ayv8er Jul 3, 2025
6a99480
implements TimeFormatToggle to Joined column
ayv8er Jul 3, 2025
83c2b62
simplifies conditionals and removes unnecessary Box component wrapper
ayv8er Jul 3, 2025
08fca04
displays standard 404 error screen on erroneous ClusterDetails query
ayv8er Jul 3, 2025
bfbf904
standardizes details page to display ETH value and time in line with …
ayv8er Jul 3, 2025
09b634a
removes redundant debouncing
ayv8er Jul 3, 2025
8212d88
moves useQueryParams hook to lib/router and updates imports and test …
ayv8er Jul 3, 2025
0c4fbb9
moves config.features.cluster
ayv8er Jul 3, 2025
861ac38
removes unnecessary 3rd column and isContractVerified since it is alw…
ayv8er Jul 3, 2025
8111308
checks clusters enable for placeholder
ayv8er Jul 3, 2025
ebcdc8e
makes isClusterClickable condition more generic for future repurpose
ayv8er Jul 3, 2025
7ad3305
splits isEvmAddress out to general purpose utility in lib/address, up…
ayv8er Jul 3, 2025
5582662
moves all cluster hooks and tests to lib/clusters folder
ayv8er Jul 3, 2025
0c4f0a0
wraps action bar with standard button wrapper
ayv8er Jul 4, 2025
a63f526
makes nextjs-routes mock condition stricter
ayv8er Jul 4, 2025
de99aa9
removes NEXT_PUBLIC_METADATA_API_HOST from main schema as it is now i…
ayv8er Jul 5, 2025
d7960c9
adds mock clusters api data
ayv8er Jul 7, 2025
b1956a3
adds pw tests for cluster detail page
ayv8er Jul 7, 2025
321b12a
adds pw tests for clusters directory page
ayv8er Jul 7, 2025
34e4d0f
adds pw tests for clustersentity ui component
ayv8er Jul 7, 2025
88646c1
adds mock envs for pw tests
ayv8er Jul 7, 2025
c668ad9
adds clusters api host and cdn url to env.pw
ayv8er Jul 7, 2025
93cec58
fixes resolve react-hooks/rules-of-hooks violation in cluster search …
ayv8er Jul 14, 2025
7b76822
throws error instead of using app error component
ayv8er Jul 14, 2025
854441e
uses semantic token to reference color as per standard method in chak…
ayv8er Jul 14, 2025
3c8239f
removes empty or loading state pw tests
ayv8er Jul 14, 2025
4fb6d7c
pw tests - uses mockAssetResponse for icons, removes redundant tests,…
ayv8er Jul 14, 2025
f1763cd
migrates all clusters pw tests from page.route to mockApiResponse
ayv8er Jul 14, 2025
a928634
updates docker generated pw screenshots
ayv8er Jul 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions configs/app/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ const rewardsApi = (() => {
});
})();

const clustersApi = (() => {
const apiHost = getEnvValue('NEXT_PUBLIC_CLUSTERS_API_HOST');
if (!apiHost) {
return;
}

return Object.freeze({
endpoint: apiHost,
});
})();

const statsApi = (() => {
const apiHost = getEnvValue('NEXT_PUBLIC_STATS_API_HOST');
if (!apiHost) {
Expand Down Expand Up @@ -143,6 +154,7 @@ const apis: Apis = Object.freeze({
general: generalApi,
admin: adminApi,
bens: bensApi,
clusters: clustersApi,
contractInfo: contractInfoApi,
metadata: metadataApi,
rewards: rewardsApi,
Expand Down
26 changes: 26 additions & 0 deletions configs/app/features/clusters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Feature } from './types';

import apis from '../apis';
import { getEnvValue } from '../utils';

const title = 'Clusters Universal Name Service';

const config: Feature<{ cdnUrl: string }> = (() => {
const cdnUrl = getEnvValue('NEXT_PUBLIC_CLUSTERS_CDN_URL') || 'https://cdn.clusters.xyz';

if (apis.clusters) {
return Object.freeze({
title,
isEnabled: true,
cdnUrl,
});
}

return Object.freeze({
title,
isEnabled: false,
cdnUrl,
});
})();

export default config;
1 change: 1 addition & 0 deletions configs/app/features/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export { default as beaconChain } from './beaconChain';
export { default as bridgedTokens } from './bridgedTokens';
export { default as blockchainInteraction } from './blockchainInteraction';
export { default as celo } from './celo';
export { default as clusters } from './clusters';
export { default as csvExport } from './csvExport';
export { default as dataAvailability } from './dataAvailability';
export { default as deFiDropdown } from './deFiDropdown';
Expand Down
4 changes: 4 additions & 0 deletions configs/envs/.env.jest
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,7 @@ NEXT_PUBLIC_STATS_API_HOST=https://localhost:3004
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://localhost:3005
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://localhost:3006
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY=xxx

# clusters feature
NEXT_PUBLIC_CLUSTERS_API_HOST=https://api.clusters.xyz
NEXT_PUBLIC_CLUSTERS_CDN_URL=https://cdn.clusters.xyz
4 changes: 4 additions & 0 deletions configs/envs/.env.localhost
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_AUTH_URL=http://localhost:3000
NEXT_PUBLIC_LOGOUT_URL=https://blockscoutcom.us.auth0.com/v2/logout

# clusters feature
NEXT_PUBLIC_CLUSTERS_API_HOST=https://api.clusters.xyz
NEXT_PUBLIC_CLUSTERS_CDN_URL=https://cdn.clusters.xyz
4 changes: 3 additions & 1 deletion configs/envs/.env.pw
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,6 @@ NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=xxx
NEXT_PUBLIC_VIEWS_ADDRESS_FORMAT=['base16','bech32']
NEXT_PUBLIC_VIEWS_ADDRESS_BECH_32_PREFIX=tom
NEXT_PUBLIC_HELIA_VERIFIED_FETCH_ENABLED=false
NEXT_PUBLIC_GAS_TRACKER_UNITS=['usd','gwei']
NEXT_PUBLIC_GAS_TRACKER_UNITS=['usd','gwei']
NEXT_PUBLIC_CLUSTERS_API_HOST=https://api.clusters.xyz
NEXT_PUBLIC_CLUSTERS_CDN_URL=https://cdn.clusters.xyz
2 changes: 2 additions & 0 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,8 @@ const schema = yup
NEXT_PUBLIC_VISUALIZE_API_BASE_PATH: yup.string(),
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: yup.string().test(urlTest),
NEXT_PUBLIC_NAME_SERVICE_API_HOST: yup.string().test(urlTest),
NEXT_PUBLIC_CLUSTERS_API_HOST: yup.string().test(urlTest),
NEXT_PUBLIC_CLUSTERS_CDN_URL: yup.string().test(urlTest),
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: yup.string().test(urlTest),
NEXT_PUBLIC_GRAPHIQL_TRANSACTION: yup
.mixed()
Expand Down
2 changes: 2 additions & 0 deletions deploy/values/review-l2/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ frontend:
NEXT_PUBLIC_USE_NEXT_JS_PROXY: true
NEXT_PUBLIC_NAVIGATION_LAYOUT: horizontal
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES: "['/blocks','/name-domains']"
NEXT_PUBLIC_CLUSTERS_API_HOST: https://api.clusters.xyz
NEXT_PUBLIC_CLUSTERS_CDN_URL: https://cdn.clusters.xyz
envFromSecret:
NEXT_PUBLIC_AUTH0_CLIENT_ID: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_AUTH0_CLIENT_ID
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID
Expand Down
2 changes: 2 additions & 0 deletions deploy/values/review/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ frontend:
PROMETHEUS_METRICS_ENABLED: true
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED: true
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED: true
NEXT_PUBLIC_CLUSTERS_API_HOST: https://api.clusters.xyz
NEXT_PUBLIC_CLUSTERS_CDN_URL: https://cdn.clusters.xyz
envFromSecret:
NEXT_PUBLIC_AUTH0_CLIENT_ID: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_AUTH0_CLIENT_ID
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID
Expand Down
12 changes: 12 additions & 0 deletions docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ All json-like values should be single-quoted. If it contains a hash (`#`) or a d
- [Verified tokens info](#verified-tokens-info)
- [Name service integration](#name-service-integration)
- [Metadata service integration](#metadata-service-integration)
- [Clusters Universal Name Service](#clusters-universal-name-service)
- [Public tag submission](#public-tag-submission)
- [Data availability](#data-availability)
- [Bridged tokens](#bridged-tokens)
Expand Down Expand Up @@ -661,6 +662,17 @@ This feature allows name tags and other public tags for addresses.

&nbsp;

### Clusters Universal Name Service

This feature integrates Clusters.xyz universal naming service, enabling users to look up and track cross-chain identities through human-readable names like "vitalik/" or "uniswap/". Unlike traditional domain services that work on single chains, clusters span multiple blockchains - one cluster name can represent addresses on Ethereum, Base, Optimism, and other networks. This integration adds cluster lookup pages (/clusters/[name]), a clusters directory (/clusters), search functionality in the main search bar, and displays cluster profile information and images throughout the explorer.

| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_CLUSTERS_API_HOST | `string` | Clusters.xyz API endpoint for fetching cluster data, directory listings, and cross-chain address mappings | Required | - | `https://example.com/clusters-api` | v2.2.0+ |
| NEXT_PUBLIC_CLUSTERS_CDN_URL | `string` | CDN base URL for serving cluster profile images and avatars displayed in search results and cluster pages | - | `https://cdn.clusters.xyz` | `https://your-cdn.example.com` | v2.2.0+ |

&nbsp;

### Public tag submission

This feature allows you to submit an application with a public address tag.
Expand Down
14 changes: 14 additions & 0 deletions icons/clusters.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions icons/hourglass.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const config: JestConfigWithTsJest = {
],
moduleNameMapper: {
'^jest/(.*)': '<rootDir>/jest/$1',
'^nextjs-routes$': '<rootDir>/jest/mocks/nextjs-routes.js',
'\\.svg$': '<rootDir>/jest/mocks/svg.js',
'^@uidotdev/usehooks$': '<rootDir>/jest/mocks/usehooks.js',
},
modulePathIgnorePatterns: [
'node_modules_linux',
Expand Down
18 changes: 18 additions & 0 deletions jest/mocks/nextjs-routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
route: jest.fn((opts) => {
const pathname = opts?.pathname;
const query = opts?.query || {};

if (pathname === '/address/[hash]') {
return `/address/${ query.hash || 'test-hash' }`;
}
if (pathname === '/tx/[hash]') {
return `/tx/${ query.hash || 'test-hash' }`;
}
if (pathname === '/clusters/[name]') {
return `/clusters/${ query.name || 'test-cluster' }`;
}

return pathname || '/';
}),
};
1 change: 1 addition & 0 deletions jest/mocks/svg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'test-file-stub';
12 changes: 12 additions & 0 deletions jest/mocks/usehooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
useClickAway: jest.fn(() => jest.fn()),
useEventListener: jest.fn(),
useLocalStorage: jest.fn(() => [ '', jest.fn() ]),
useSessionStorage: jest.fn(() => [ '', jest.fn() ]),
useToggle: jest.fn(() => [ false, jest.fn() ]),
useDebounce: jest.fn((value) => value),
useThrottle: jest.fn((value) => value),
usePrevious: jest.fn(),
useCounter: jest.fn(() => ({ count: 0, increment: jest.fn(), decrement: jest.fn(), reset: jest.fn() })),
useCopyToClipboard: jest.fn(() => [ '', jest.fn() ]),
};
6 changes: 6 additions & 0 deletions lib/address/isEvmAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ADDRESS_REGEXP } from 'toolkit/utils/regexp';

export function isEvmAddress(address: string): boolean {
if (!address) return false;
return ADDRESS_REGEXP.test(address.trim());
}
6 changes: 6 additions & 0 deletions lib/api/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import type { AdminApiResourceName, AdminApiResourcePayload } from './services/a
import { ADMIN_API_RESOURCES } from './services/admin';
import { BENS_API_RESOURCES } from './services/bens';
import type { BensApiResourceName, BensApiResourcePayload, BensApiPaginationFilters, BensApiPaginationSorting } from './services/bens';
import { CLUSTERS_API_RESOURCES } from './services/clusters';
import type { ClustersApiResourceName, ClustersApiResourcePayload, ClustersApiPaginationFilters, ClustersApiPaginationSorting } from './services/clusters';
import { CONTRACT_INFO_API_RESOURCES } from './services/contractInfo';
import type { ContractInfoApiPaginationFilters, ContractInfoApiResourceName, ContractInfoApiResourcePayload } from './services/contractInfo';
import { GENERAL_API_RESOURCES } from './services/general';
Expand All @@ -27,6 +29,7 @@ import type { VisualizeApiResourceName, VisualizeApiResourcePayload } from './se
export const RESOURCES = {
admin: ADMIN_API_RESOURCES,
bens: BENS_API_RESOURCES,
clusters: CLUSTERS_API_RESOURCES,
contractInfo: CONTRACT_INFO_API_RESOURCES,
general: GENERAL_API_RESOURCES,
metadata: METADATA_API_RESOURCES,
Expand All @@ -48,6 +51,7 @@ export type ResourcePath = string;
export type ResourcePayload<R extends ResourceName> =
R extends AdminApiResourceName ? AdminApiResourcePayload<R> :
R extends BensApiResourceName ? BensApiResourcePayload<R> :
R extends ClustersApiResourceName ? ClustersApiResourcePayload<R> :
R extends ContractInfoApiResourceName ? ContractInfoApiResourcePayload<R> :
R extends GeneralApiResourceName ? GeneralApiResourcePayload<R> :
R extends MetadataApiResourceName ? MetadataApiResourcePayload<R> :
Expand Down Expand Up @@ -83,6 +87,7 @@ export type ResourceErrorAccount<T> = ResourceError<{ errors: T }>;
/* eslint-disable @stylistic/indent */
export type PaginationFilters<R extends ResourceName> =
R extends BensApiResourceName ? BensApiPaginationFilters<R> :
R extends ClustersApiResourceName ? ClustersApiPaginationFilters :
R extends GeneralApiResourceName ? GeneralApiPaginationFilters<R> :
R extends ContractInfoApiResourceName ? ContractInfoApiPaginationFilters<R> :
R extends TacOperationLifecycleApiResourceName ? TacOperationLifecycleApiPaginationFilters<R> :
Expand All @@ -94,6 +99,7 @@ export const SORTING_FIELDS = [ 'sort', 'order' ];
/* eslint-disable @stylistic/indent */
export type PaginationSorting<R extends ResourceName> =
R extends BensApiResourceName ? BensApiPaginationSorting<R> :
R extends ClustersApiResourceName ? ClustersApiPaginationSorting :
R extends GeneralApiResourceName ? GeneralApiPaginationSorting<R> :
never;
/* eslint-enable @stylistic/indent */
Expand Down
57 changes: 57 additions & 0 deletions lib/api/services/clusters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { ApiResource } from '../types';
import type {
ClustersByAddressResponse,
ClusterByNameResponse,
ClustersLeaderboardResponse,
ClustersDirectoryResponse,
ClustersByAddressQueryParams,
ClusterByNameQueryParams,
ClustersLeaderboardQueryParams,
ClustersDirectoryQueryParams,
ClusterByIdQueryParams,
ClusterByIdResponse,
} from 'types/api/clusters';

export const CLUSTERS_API_RESOURCES = {
get_clusters_by_address: {
path: '/v1/trpc/names.getNamesByOwnerAddress',
pathParams: [],
},
get_cluster_by_name: {
path: '/v1/trpc/names.get',
pathParams: [],
},
get_cluster_by_id: {
path: '/v1/trpc/clusters.getClusterById',
pathParams: [],
},
get_leaderboard: {
path: '/v1/trpc/names.leaderboard',
pathParams: [],
},
get_directory: {
path: '/v1/trpc/names.search',
pathParams: [],
},
} satisfies Record<string, ApiResource>;

export type ClustersApiResourceName = `clusters:${ keyof typeof CLUSTERS_API_RESOURCES }`;

export type ClustersApiResourcePayload<R extends ClustersApiResourceName> =
R extends 'clusters:get_clusters_by_address' ? ClustersByAddressResponse :
R extends 'clusters:get_cluster_by_name' ? ClusterByNameResponse :
R extends 'clusters:get_cluster_by_id' ? ClusterByIdResponse :
R extends 'clusters:get_leaderboard' ? ClustersLeaderboardResponse :
R extends 'clusters:get_directory' ? ClustersDirectoryResponse :
never;

export type ClustersApiQueryParams<R extends ClustersApiResourceName> =
R extends 'clusters:get_clusters_by_address' ? ClustersByAddressQueryParams :
R extends 'clusters:get_cluster_by_name' ? ClusterByNameQueryParams :
R extends 'clusters:get_cluster_by_id' ? ClusterByIdQueryParams :
R extends 'clusters:get_leaderboard' ? ClustersLeaderboardQueryParams :
R extends 'clusters:get_directory' ? ClustersDirectoryQueryParams :
never;

export type ClustersApiPaginationFilters = never;
export type ClustersApiPaginationSorting = never;
2 changes: 1 addition & 1 deletion lib/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type ApiName = 'general' | 'admin' | 'bens' | 'contractInfo' | 'metadata' | 'rewards' | 'stats' | 'visualize' | 'tac';
export type ApiName = 'general' | 'admin' | 'bens' | 'clusters' | 'contractInfo' | 'metadata' | 'rewards' | 'stats' | 'visualize' | 'tac';

export interface ApiResource {
path: string;
Expand Down
Loading