Commit adb1b0c9 authored by Max Alekseenko's avatar Max Alekseenko

fetch dapps from admin service

parent 504de39d
...@@ -7,21 +7,31 @@ import { getEnvValue, getExternalAssetFilePath } from '../utils'; ...@@ -7,21 +7,31 @@ import { getEnvValue, getExternalAssetFilePath } from '../utils';
const configUrl = getExternalAssetFilePath('NEXT_PUBLIC_MARKETPLACE_CONFIG_URL'); const configUrl = getExternalAssetFilePath('NEXT_PUBLIC_MARKETPLACE_CONFIG_URL');
const submitFormUrl = getEnvValue('NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM'); const submitFormUrl = getEnvValue('NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM');
const categoriesUrl = getExternalAssetFilePath('NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL'); const categoriesUrl = getExternalAssetFilePath('NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL');
const adminServiceApiHost = getEnvValue('NEXT_PUBLIC_ADMIN_SERVICE_API_HOST');
const title = 'Marketplace'; const title = 'Marketplace';
const config: Feature<{ configUrl: string; submitFormUrl: string; categoriesUrl: string | undefined }> = (() => { const config: Feature<{
configUrl: string | undefined;
submitFormUrl: string;
categoriesUrl: string | undefined;
api: { endpoint: string; basePath: string } | undefined;
}> = (() => {
if ( if (
chain.rpcUrl && chain.rpcUrl &&
configUrl && (configUrl || adminServiceApiHost) &&
submitFormUrl submitFormUrl
) { ) {
return Object.freeze({ return Object.freeze({
title, title,
isEnabled: true, isEnabled: true,
configUrl, configUrl: adminServiceApiHost ? undefined : configUrl,
submitFormUrl, submitFormUrl,
categoriesUrl, categoriesUrl,
api: adminServiceApiHost ? {
endpoint: adminServiceApiHost,
basePath: '',
} : undefined,
}); });
} }
......
...@@ -82,6 +82,7 @@ import type { VerifiedContractsSorting } from 'types/api/verifiedContracts'; ...@@ -82,6 +82,7 @@ import type { VerifiedContractsSorting } from 'types/api/verifiedContracts';
import type { VisualizedContract } from 'types/api/visualization'; import type { VisualizedContract } from 'types/api/visualization';
import type { WithdrawalsResponse, WithdrawalsCounters } from 'types/api/withdrawals'; import type { WithdrawalsResponse, WithdrawalsCounters } from 'types/api/withdrawals';
import type { ZkEvmL2TxnBatch, ZkEvmL2TxnBatchesItem, ZkEvmL2TxnBatchesResponse, ZkEvmL2TxnBatchTxs } from 'types/api/zkEvmL2TxnBatches'; import type { ZkEvmL2TxnBatch, ZkEvmL2TxnBatchesItem, ZkEvmL2TxnBatchesResponse, ZkEvmL2TxnBatchTxs } from 'types/api/zkEvmL2TxnBatches';
import type { MarketplaceAppOverview } from 'types/client/marketplace';
import type { ArrayElement } from 'types/utils'; import type { ArrayElement } from 'types/utils';
import config from 'configs/app'; import config from 'configs/app';
...@@ -214,6 +215,20 @@ export const RESOURCES = { ...@@ -214,6 +215,20 @@ export const RESOURCES = {
filterFields: [ 'name' as const, 'only_active' as const ], filterFields: [ 'name' as const, 'only_active' as const ],
}, },
// MARKETPLACE
marketplace_dapps: {
path: '/api/v1/chains/:chainId/marketplace/dapps',
pathParams: [ 'chainId' as const ],
endpoint: getFeaturePayload(config.features.marketplace)?.api?.endpoint,
basePath: getFeaturePayload(config.features.marketplace)?.api?.basePath,
},
marketplace_dapp: {
path: '/api/v1/chains/:chainId/marketplace/dapps/:dappId',
pathParams: [ 'chainId' as const, 'dappId' as const ],
endpoint: getFeaturePayload(config.features.marketplace)?.api?.endpoint,
basePath: getFeaturePayload(config.features.marketplace)?.api?.basePath,
},
// VISUALIZATION // VISUALIZATION
visualize_sol2uml: { visualize_sol2uml: {
path: '/api/v1/solidity\\:visualize-contracts', path: '/api/v1/solidity\\:visualize-contracts',
...@@ -772,6 +787,8 @@ Q extends 'domains_lookup' ? EnsDomainLookupResponse : ...@@ -772,6 +787,8 @@ Q extends 'domains_lookup' ? EnsDomainLookupResponse :
Q extends 'user_ops' ? UserOpsResponse : Q extends 'user_ops' ? UserOpsResponse :
Q extends 'user_op' ? UserOp : Q extends 'user_op' ? UserOp :
Q extends 'user_ops_account' ? UserOpsAccount : Q extends 'user_ops_account' ? UserOpsAccount :
Q extends 'marketplace_dapps' ? Array<MarketplaceAppOverview> :
Q extends 'marketplace_dapp' ? MarketplaceAppOverview :
never; never;
/* eslint-enable @typescript-eslint/indent */ /* eslint-enable @typescript-eslint/indent */
......
...@@ -6,12 +6,12 @@ import { MarketplaceCategory } from 'types/client/marketplace'; ...@@ -6,12 +6,12 @@ import { MarketplaceCategory } from 'types/client/marketplace';
import config from 'configs/app'; import config from 'configs/app';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useApiQuery from 'lib/api/useApiQuery';
import useFeatureValue from 'lib/growthbook/useFeatureValue'; import useFeatureValue from 'lib/growthbook/useFeatureValue';
import useApiFetch from 'lib/hooks/useFetch'; import useApiFetch from 'lib/hooks/useFetch';
import { MARKETPLACE_APP } from 'stubs/marketplace'; import { MARKETPLACE_APP } from 'stubs/marketplace';
const feature = config.features.marketplace; const feature = config.features.marketplace;
const configUrl = feature.isEnabled ? feature.configUrl : '';
function isAppNameMatches(q: string, app: MarketplaceAppOverview) { function isAppNameMatches(q: string, app: MarketplaceAppOverview) {
return app.title.toLowerCase().includes(q.toLowerCase()); return app.title.toLowerCase().includes(q.toLowerCase());
...@@ -47,19 +47,36 @@ function sortApps(apps: Array<MarketplaceAppOverview>, isExperiment: boolean) { ...@@ -47,19 +47,36 @@ function sortApps(apps: Array<MarketplaceAppOverview>, isExperiment: boolean) {
}); });
} }
export default function useMarketplaceApps(filter: string, selectedCategoryId: string = MarketplaceCategory.ALL, favoriteApps: Array<string> = []) { function useAppsQuery() {
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
const { value: isExperiment } = useFeatureValue('marketplace_exp', false); const { value: isExperiment } = useFeatureValue('marketplace_exp', false);
const { isPlaceholderData, isError, error, data } = useQuery<unknown, ResourceError<unknown>, Array<MarketplaceAppOverview>>({ const placeholderData = feature.isEnabled ? Array(9).fill(MARKETPLACE_APP) : undefined;
const data1 = useQuery<unknown, ResourceError<unknown>, Array<MarketplaceAppOverview>>({
queryKey: [ 'marketplace-apps' ], queryKey: [ 'marketplace-apps' ],
queryFn: async() => apiFetch(configUrl, undefined, { resource: 'marketplace-apps' }), queryFn: async() => apiFetch(feature.isEnabled && feature.configUrl ? feature.configUrl : '', undefined, { resource: 'marketplace-apps' }),
select: (data) => sortApps(data as Array<MarketplaceAppOverview>, isExperiment), select: (data) => sortApps(data as Array<MarketplaceAppOverview>, isExperiment),
placeholderData: feature.isEnabled ? Array(9).fill(MARKETPLACE_APP) : undefined, placeholderData,
staleTime: Infinity, staleTime: Infinity,
enabled: feature.isEnabled, enabled: feature.isEnabled,
}); });
const data2 = useApiQuery('marketplace_dapps', {
pathParams: { chainId: config.chain.id },
queryOptions: {
select: (data) => sortApps(data as Array<MarketplaceAppOverview>, isExperiment),
placeholderData,
enabled: feature.isEnabled,
},
});
return feature.isEnabled && feature.configUrl ? data1 : data2;
}
export default function useMarketplaceApps(filter: string, selectedCategoryId: string = MarketplaceCategory.ALL, favoriteApps: Array<string> = []) {
const { isPlaceholderData, isError, error, data } = useAppsQuery();
const displayedApps = React.useMemo(() => { const displayedApps = React.useMemo(() => {
return data?.filter(app => isAppNameMatches(filter, app) && isAppCategoryMatches(selectedCategoryId, app, favoriteApps)) || []; return data?.filter(app => isAppNameMatches(filter, app) && isAppCategoryMatches(selectedCategoryId, app, favoriteApps)) || [];
}, [ selectedCategoryId, data, filter, favoriteApps ]); }, [ selectedCategoryId, data, filter, favoriteApps ]);
......
...@@ -10,6 +10,7 @@ import { route } from 'nextjs-routes'; ...@@ -10,6 +10,7 @@ import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useApiQuery from 'lib/api/useApiQuery';
import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError'; import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError';
import useApiFetch from 'lib/hooks/useFetch'; import useApiFetch from 'lib/hooks/useFetch';
import * as metadata from 'lib/metadata'; import * as metadata from 'lib/metadata';
...@@ -19,7 +20,6 @@ import ContentLoader from 'ui/shared/ContentLoader'; ...@@ -19,7 +20,6 @@ import ContentLoader from 'ui/shared/ContentLoader';
import useMarketplaceWallet from '../marketplace/useMarketplaceWallet'; import useMarketplaceWallet from '../marketplace/useMarketplaceWallet';
const feature = config.features.marketplace; const feature = config.features.marketplace;
const configUrl = feature.isEnabled ? feature.configUrl : '';
const IFRAME_SANDBOX_ATTRIBUTE = 'allow-forms allow-orientation-lock ' + const IFRAME_SANDBOX_ATTRIBUTE = 'allow-forms allow-orientation-lock ' +
'allow-pointer-lock allow-popups-to-escape-sandbox ' + 'allow-pointer-lock allow-popups-to-escape-sandbox ' +
...@@ -94,16 +94,13 @@ const MarketplaceAppContent = ({ address, data, isPending }: Props) => { ...@@ -94,16 +94,13 @@ const MarketplaceAppContent = ({ address, data, isPending }: Props) => {
); );
}; };
const MarketplaceApp = () => { function useAppQuery(id: string) {
const { address, sendTransaction, signMessage, signTypedData } = useMarketplaceWallet();
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
const router = useRouter();
const id = getQueryParamString(router.query.id);
const query = useQuery<unknown, ResourceError<unknown>, MarketplaceAppOverview>({ const data1 = useQuery<unknown, ResourceError<unknown>, MarketplaceAppOverview>({
queryKey: [ 'marketplace-apps', id ], queryKey: [ 'marketplace-apps', id ],
queryFn: async() => { queryFn: async() => {
const configUrl = feature.isEnabled && feature.configUrl ? feature.configUrl : '';
const result = await apiFetch<Array<MarketplaceAppOverview>, unknown>(configUrl, undefined, { resource: 'marketplace-apps' }); const result = await apiFetch<Array<MarketplaceAppOverview>, unknown>(configUrl, undefined, { resource: 'marketplace-apps' });
if (!Array.isArray(result)) { if (!Array.isArray(result)) {
throw result; throw result;
...@@ -117,6 +114,24 @@ const MarketplaceApp = () => { ...@@ -117,6 +114,24 @@ const MarketplaceApp = () => {
}, },
enabled: feature.isEnabled, enabled: feature.isEnabled,
}); });
const data2 = useApiQuery('marketplace_dapp', {
pathParams: { chainId: config.chain.id, dappId: id },
queryOptions: {
enabled: feature.isEnabled,
},
});
return feature.isEnabled && feature.configUrl ? data1 : data2;
}
const MarketplaceApp = () => {
const { address, sendTransaction, signMessage, signTypedData } = useMarketplaceWallet();
const router = useRouter();
const id = getQueryParamString(router.query.id);
const query = useAppQuery(id);
const { data, isPending } = query; const { data, isPending } = query;
useEffect(() => { useEffect(() => {
......
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