Skip to content

Commit

Permalink
feat: Algolia Removal (#23)
Browse files Browse the repository at this point in the history
* Initial graph client impl

* Fetching logic

* Generalize types

* Validate graph env

* Trim name

Signed-off-by: Wolmin <[email protected]>
  • Loading branch information
Wolmin committed Jan 15, 2025
1 parent 5cad868 commit 907a856
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 28 deletions.
8 changes: 2 additions & 6 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -909,17 +909,13 @@ const schema = yup
NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY: yup.string(), // DEPRECATED
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: yup.string(),
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN: yup.string(),
NEXT_PUBLIC_UNIVERSAL_PROFILES_API_URL: yup.string(),
NEXT_PUBLIC_GRAPH_URL: yup.string(),
NEXT_PUBLIC_GROWTH_BOOK_CLIENT_KEY: yup.string(),
NEXT_PUBLIC_ROLLBAR_CLIENT_TOKEN: yup.string(),
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY: yup.string(),
NEXT_PUBLIC_UP_API_URL: yup.string(),
NEXT_PUBLIC_UNIVERSAL_PROFILES_API_URL: yup.string(),

// Misc
NEXT_PUBLIC_USE_NEXT_JS_PROXY: yup.boolean(),
NEXT_PUBLIC_ALGOLIA_APP_ID: yup.string(),
NEXT_PUBLIC_ALGOLIA_API_KEY: yup.string(),
NEXT_PUBLIC_ALGOLIA_INDEX_NAME: yup.string(),
})
.concat(accountSchema)
.concat(adsBannerSchema)
Expand Down
6 changes: 2 additions & 4 deletions docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,8 @@ Settings for meta tags, OG tags and SEO
| NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED | `boolean` | Set to `true` if SolidityScan reports are supported | - | - | `true` | v1.19.0+ |
| NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS | `Array<'solidity-hardhat' \| 'solidity-foundry'>` | Pass an array of additional methods from which users can choose while verifying a smart contract. Both methods are available by default, pass `'none'` string to disable them all. | - | - | `['solidity-hardhat']` | v1.33.0+ |
| NEXT_PUBLIC_VIEWS_CONTRACT_LANGUAGE_FILTERS | `Array<'solidity' \| 'vyper' \| 'yul' \| 'scilla'>` | Pass an array of contract languages that will be displayed as options in the filter on the verified contract page. | - | `['solidity','vyper','yul']` | `['solidity','vyper','yul','scilla']` | v1.37.0+ |
| NEXT_PUBLIC_UNIVERSAL_PROFILES_API_URL | `string` | LUKSO UP API URL used for getting various UP data | - | - | `https://api.universalprofile.com` |
| NEXT_PUBLIC_ALGOLIA_APP_ID | `string` | Algolia App's ID | - | - | `ABCD1234` |
| NEXT_PUBLIC_ALGOLIA_API_KEY | `string` | Algolia API key used for authenticating requests | - | - | `abcd1234defg5678` |
| NEXT_PUBLIC_ALGOLIA_INDEX_NAME | `string` | Index name from where data should be requested | - | - | `prod_mainnet_data` |
| NEXT_PUBLIC_UNIVERSAL_PROFILES_API_URL | `string` | LUKSO UNIVERSAL PROFILE API URL used for getting various universal profile data | - | - | `https://api.universalprofile.com` | - |
| NEXT_PUBLIC_GRAPH_URL | `string` | URL of LUKSO Graph Indexer | - | - | `https://envio.mainnet.lukso.dev/`| - |

##### Address views list
| Id | Description |
Expand Down
11 changes: 0 additions & 11 deletions lib/api/buildUniversalProfileUrl.ts

This file was deleted.

47 changes: 47 additions & 0 deletions lib/api/graphClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { GraphResponse } from 'types/api/universalProfile';

import { getEnvValue } from 'configs/app/utils';

import { constructQuery } from './graphQueries';
import type { QueryOperation, SearchProfileQueryResponse } from './graphTypes';

const graphUrl = getEnvValue('NEXT_PUBLIC_GRAPH_URL') || '';

type FetchFunc<T> = (queryParams?: string) => Promise<GraphResponse<T> | null>;

type GraphClient = {
getProfiles: FetchFunc<SearchProfileQueryResponse>;
};

const queryParamsToGraphQuery = (operationName: QueryOperation, queryParams?: string): string => {
const query = constructQuery(operationName, queryParams);

return JSON.stringify({
operationName: operationName,
query: query,
});
};

const fetchQuery = <T>(operationName: QueryOperation): FetchFunc<T> => {
return async(queryParams?: string): Promise<GraphResponse<T> | null> => {
const query = queryParamsToGraphQuery(operationName, queryParams);

try {
const resp = await fetch(graphUrl, {
method: 'POST',
headers: {},
body: query,
});
const json = await resp.json();
return json as GraphResponse<T>;
} catch (err) {
return null;
}
};
};

const createGraphClient = (): GraphClient => ({
getProfiles: fetchQuery<SearchProfileQueryResponse>('search_profiles'),
});

export const graphClient: GraphClient = createGraphClient();
25 changes: 25 additions & 0 deletions lib/api/graphQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { QueryOperation } from './graphTypes';

type QueryConstructor = (queryParams?: string) => string;

export const constructQuery = (operationType: QueryOperation, queryParams?: string) => {
const queryConstruct = queryConstructors[operationType];

return queryConstruct(queryParams);
};

export const searchProfileQuery = (queryParams?: string): string => `query search_profiles {
search_profiles(args: { search: "${ queryParams }" }) {
profileImages(order_by: { width: asc }) {
src,
width,
},
id,
name,
fullName,
}
}`;

const queryConstructors: Record<QueryOperation, QueryConstructor> = {
search_profiles: searchProfileQuery,
};
18 changes: 18 additions & 0 deletions lib/api/graphTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export type ProfileImage = {
src: string;
width: number;
};

export type SearchProfileQueryResponse = {
profileImages: Array<ProfileImage>;
id: string;
name: string;
fullName: string;
};

export type GraphQuery = {
operationName: string;
query: string;
};

export type QueryOperation = 'search_profiles';
20 changes: 13 additions & 7 deletions lib/api/useUniversalProfileApiFetch.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';

import type { SearchResultAddressOrContractOrUniversalProfile } from '../../types/api/search';
import type { UniversalProfileProxyResponse } from '../../types/api/universalProfile';

import type { Params as FetchParams } from 'lib/hooks/useFetch';

import { algoliaIndex } from './buildUniversalProfileUrl';
import { graphClient } from './graphClient';
import type { SearchProfileQueryResponse } from './graphTypes';
import { isUniversalProfileEnabled } from './isUniversalProfileEnabled';
import type { ResourceName, ResourcePathParams } from './resources';

Expand All @@ -22,13 +22,19 @@ export default function useUniversalProfileApiFetch() {
return [] as Array<SearchResultAddressOrContractOrUniversalProfile>;
}
try {
const { hits } = await algoliaIndex.search(queryParams);
return hits.map<SearchResultAddressOrContractOrUniversalProfile>((hit) => {
const hitAsUp = hit as unknown as UniversalProfileProxyResponse;
const result = await graphClient.getProfiles(queryParams);
if (result == null) {
return [] as Array<SearchResultAddressOrContractOrUniversalProfile>;
}

const hits = result.data.search_profiles as Array<SearchProfileQueryResponse>;

return hits.map<SearchResultAddressOrContractOrUniversalProfile>((hit: SearchProfileQueryResponse) => {
const hitAsUp = hit as unknown as SearchProfileQueryResponse;
return {
type: 'universal_profile',
name: hitAsUp.hasProfileName ? hitAsUp.LSP3Profile.name : null,
address: hit.objectID,
name: hitAsUp.name !== '' ? hitAsUp.name.trim() : null,
address: hit.id,
is_smart_contract_verified: false,
};
});
Expand Down
1 change: 1 addition & 0 deletions nextjs/csp/policies/universalprofile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export function universalProfile(): CspDev.DirectiveDescriptor {
'api.universalprofile.cloud',
'*.algolianet.com',
'*.algolia.net',
'envio.mainnet.lukso.dev',
],
};
}
8 changes: 8 additions & 0 deletions types/api/universalProfile.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { QueryOperation } from 'lib/api/graphTypes';

export type UniversalProfileProxyResponse = {
type: string;
hasProfileName: boolean;
Expand Down Expand Up @@ -25,3 +27,9 @@ export type UniversalProfileAlgoliaResponse = {
};
};
};

export type GraphResponse<T> = {
data: {
[key in QueryOperation]: Array<T>;
};
};

0 comments on commit 907a856

Please sign in to comment.