mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
698 lines
27 KiB
TypeScript
698 lines
27 KiB
TypeScript
declare module 'yup' {
|
|
interface StringSchema {
|
|
// Yup's URL validator is not perfect so we made our own
|
|
// https://github.com/jquense/yup/pull/1859
|
|
url(): never;
|
|
}
|
|
}
|
|
|
|
import * as yup from 'yup';
|
|
|
|
import type { AdButlerConfig } from '../../../types/client/adButlerConfig';
|
|
import { SUPPORTED_AD_TEXT_PROVIDERS, SUPPORTED_AD_BANNER_PROVIDERS, SUPPORTED_AD_BANNER_ADDITIONAL_PROVIDERS } from '../../../types/client/adProviders';
|
|
import type { AdTextProviders, AdBannerProviders, AdBannerAdditionalProviders } from '../../../types/client/adProviders';
|
|
import type { ContractCodeIde } from '../../../types/client/contract';
|
|
import type { DeFiDropdownItem } from '../../../types/client/deFiDropdown';
|
|
import { GAS_UNITS } from '../../../types/client/gasTracker';
|
|
import type { GasUnit } from '../../../types/client/gasTracker';
|
|
import type { MarketplaceAppOverview, MarketplaceAppSecurityReportRaw, MarketplaceAppSecurityReport } from '../../../types/client/marketplace';
|
|
import type { MultichainProviderConfig } from '../../../types/client/multichainProviderConfig';
|
|
import { NAVIGATION_LINK_IDS } from '../../../types/client/navigation';
|
|
import type { NavItemExternal, NavigationLinkId, NavigationLayout } from '../../../types/client/navigation';
|
|
import { ROLLUP_TYPES } from '../../../types/client/rollup';
|
|
import type { BridgedTokenChain, TokenBridge } from '../../../types/client/token';
|
|
import { PROVIDERS as TX_INTERPRETATION_PROVIDERS } from '../../../types/client/txInterpretation';
|
|
import { VALIDATORS_CHAIN_TYPE } from '../../../types/client/validators';
|
|
import type { ValidatorsChainType } from '../../../types/client/validators';
|
|
import type { WalletType } from '../../../types/client/wallets';
|
|
import { SUPPORTED_WALLETS } from '../../../types/client/wallets';
|
|
import type { CustomLink, CustomLinksGroup } from '../../../types/footerLinks';
|
|
import { CHAIN_INDICATOR_IDS } from '../../../types/homepage';
|
|
import type { ChainIndicatorId } from '../../../types/homepage';
|
|
import { type NetworkVerificationType, type NetworkExplorer, type FeaturedNetwork, NETWORK_GROUPS } from '../../../types/networks';
|
|
import { COLOR_THEME_IDS } from '../../../types/settings';
|
|
import type { AddressViewId } from '../../../types/views/address';
|
|
import { ADDRESS_VIEWS_IDS, IDENTICON_TYPES } from '../../../types/views/address';
|
|
import { BLOCK_FIELDS_IDS } from '../../../types/views/block';
|
|
import type { BlockFieldId } from '../../../types/views/block';
|
|
import type { NftMarketplaceItem } from '../../../types/views/nft';
|
|
import type { TxAdditionalFieldsId, TxFieldsId } from '../../../types/views/tx';
|
|
import { TX_ADDITIONAL_FIELDS_IDS, TX_FIELDS_IDS } from '../../../types/views/tx';
|
|
|
|
import { replaceQuotes } from '../../../configs/app/utils';
|
|
import * as regexp from '../../../lib/regexp';
|
|
import type { IconName } from '../../../ui/shared/IconSvg';
|
|
|
|
const protocols = [ 'http', 'https' ];
|
|
|
|
const urlTest: yup.TestConfig = {
|
|
name: 'url',
|
|
test: (value: unknown) => {
|
|
if (!value) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
if (typeof value === 'string') {
|
|
new URL(value);
|
|
return true;
|
|
}
|
|
} catch (error) {}
|
|
|
|
return false;
|
|
},
|
|
message: '${path} is not a valid URL',
|
|
exclusive: true,
|
|
};
|
|
|
|
const marketplaceAppSchema: yup.ObjectSchema<MarketplaceAppOverview> = yup
|
|
.object({
|
|
id: yup.string().required(),
|
|
external: yup.boolean(),
|
|
title: yup.string().required(),
|
|
logo: yup.string().test(urlTest).required(),
|
|
logoDarkMode: yup.string().test(urlTest),
|
|
shortDescription: yup.string().required(),
|
|
categories: yup.array().of(yup.string().required()).required(),
|
|
url: yup.string().test(urlTest).required(),
|
|
author: yup.string().required(),
|
|
description: yup.string().required(),
|
|
site: yup.string().test(urlTest),
|
|
twitter: yup.string().test(urlTest),
|
|
telegram: yup.string().test(urlTest),
|
|
github: yup.lazy(value =>
|
|
Array.isArray(value) ?
|
|
yup.array().of(yup.string().required().test(urlTest)) :
|
|
yup.string().test(urlTest),
|
|
),
|
|
discord: yup.string().test(urlTest),
|
|
internalWallet: yup.boolean(),
|
|
priority: yup.number(),
|
|
});
|
|
|
|
const issueSeverityDistributionSchema: yup.ObjectSchema<MarketplaceAppSecurityReport['overallInfo']['issueSeverityDistribution']> = yup
|
|
.object({
|
|
critical: yup.number().required(),
|
|
gas: yup.number().required(),
|
|
high: yup.number().required(),
|
|
informational: yup.number().required(),
|
|
low: yup.number().required(),
|
|
medium: yup.number().required(),
|
|
});
|
|
|
|
const solidityscanReportSchema: yup.ObjectSchema<MarketplaceAppSecurityReport['contractsData'][number]['solidityScanReport']> = yup
|
|
.object({
|
|
contractname: yup.string().required(),
|
|
scan_status: yup.string().required(),
|
|
scan_summary: yup
|
|
.object({
|
|
issue_severity_distribution: issueSeverityDistributionSchema.required(),
|
|
lines_analyzed_count: yup.number().required(),
|
|
scan_time_taken: yup.number().required(),
|
|
score: yup.string().required(),
|
|
score_v2: yup.string().required(),
|
|
threat_score: yup.string().required(),
|
|
})
|
|
.required(),
|
|
scanner_reference_url: yup.string().test(urlTest).required(),
|
|
});
|
|
|
|
const contractDataSchema: yup.ObjectSchema<MarketplaceAppSecurityReport['contractsData'][number]> = yup
|
|
.object({
|
|
address: yup.string().required(),
|
|
isVerified: yup.boolean().required(),
|
|
solidityScanReport: solidityscanReportSchema.nullable().notRequired(),
|
|
});
|
|
|
|
const chainsDataSchema = yup.lazy((objValue) => {
|
|
let schema = yup.object();
|
|
Object.keys(objValue).forEach((key) => {
|
|
schema = schema.shape({
|
|
[key]: yup.object({
|
|
overallInfo: yup.object({
|
|
verifiedNumber: yup.number().required(),
|
|
totalContractsNumber: yup.number().required(),
|
|
solidityScanContractsNumber: yup.number().required(),
|
|
securityScore: yup.number().required(),
|
|
issueSeverityDistribution: issueSeverityDistributionSchema.required(),
|
|
}).required(),
|
|
contractsData: yup.array().of(contractDataSchema).required(),
|
|
}),
|
|
});
|
|
});
|
|
return schema;
|
|
});
|
|
|
|
const securityReportSchema: yup.ObjectSchema<MarketplaceAppSecurityReportRaw> = yup
|
|
.object({
|
|
appName: yup.string().required(),
|
|
chainsData: chainsDataSchema,
|
|
});
|
|
|
|
const marketplaceSchema = yup
|
|
.object()
|
|
.shape({
|
|
NEXT_PUBLIC_MARKETPLACE_ENABLED: yup.boolean(),
|
|
NEXT_PUBLIC_MARKETPLACE_CONFIG_URL: yup
|
|
.array()
|
|
.json()
|
|
.of(marketplaceAppSchema)
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema,
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_CONFIG_URL cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL: yup
|
|
.array()
|
|
.json()
|
|
.of(yup.string())
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema,
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema.test(urlTest).required(),
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema.test(urlTest),
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL: yup
|
|
.array()
|
|
.json()
|
|
.of(securityReportSchema)
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema,
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_FEATURED_APP: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema,
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_FEATURED_APP cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema.test(urlTest),
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema.test(urlTest),
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_RATING_AIRTABLE_API_KEY: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema,
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_RATING_AIRTABLE_API_KEY cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
NEXT_PUBLIC_MARKETPLACE_RATING_AIRTABLE_BASE_ID: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
|
|
is: true,
|
|
then: (schema) => schema,
|
|
// eslint-disable-next-line max-len
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_RATING_AIRTABLE_BASE_ID cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
|
|
}),
|
|
});
|
|
|
|
const beaconChainSchema = yup
|
|
.object()
|
|
.shape({
|
|
NEXT_PUBLIC_HAS_BEACON_CHAIN: yup.boolean(),
|
|
NEXT_PUBLIC_BEACON_CHAIN_CURRENCY_SYMBOL: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_HAS_BEACON_CHAIN', {
|
|
is: (value: boolean) => value,
|
|
then: (schema) => schema.min(1).optional(),
|
|
otherwise: (schema) => schema.max(
|
|
-1,
|
|
'NEXT_PUBLIC_BEACON_CHAIN_CURRENCY_SYMBOL cannot not be used if NEXT_PUBLIC_HAS_BEACON_CHAIN is not set to "true"',
|
|
),
|
|
}),
|
|
});
|
|
|
|
const rollupSchema = yup
|
|
.object()
|
|
.shape({
|
|
NEXT_PUBLIC_ROLLUP_TYPE: yup.string().oneOf(ROLLUP_TYPES),
|
|
NEXT_PUBLIC_ROLLUP_L1_BASE_URL: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
|
|
is: (value: string) => value,
|
|
then: (schema) => schema.test(urlTest).required(),
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined'),
|
|
}),
|
|
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
|
|
is: (value: string) => value === 'optimistic',
|
|
then: (schema) => schema.test(urlTest).required(),
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL can be used only if NEXT_PUBLIC_ROLLUP_TYPE is set to \'optimistic\' '),
|
|
}),
|
|
});
|
|
|
|
const adButlerConfigSchema = yup
|
|
.object<AdButlerConfig>()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.when('NEXT_PUBLIC_AD_BANNER_PROVIDER', {
|
|
is: (value: AdBannerProviders) => value === 'adbutler',
|
|
then: (schema) => schema
|
|
.shape({
|
|
id: yup.string().required(),
|
|
width: yup.number().positive().required(),
|
|
height: yup.number().positive().required(),
|
|
})
|
|
.required(),
|
|
})
|
|
.when('NEXT_PUBLIC_AD_BANNER_ADDITIONAL_PROVIDER', {
|
|
is: (value: AdBannerProviders) => value === 'adbutler',
|
|
then: (schema) => schema
|
|
.shape({
|
|
id: yup.string().required(),
|
|
width: yup.number().positive().required(),
|
|
height: yup.number().positive().required(),
|
|
})
|
|
.required(),
|
|
});
|
|
|
|
const adsBannerSchema = yup
|
|
.object()
|
|
.shape({
|
|
NEXT_PUBLIC_AD_BANNER_PROVIDER: yup.string<AdBannerProviders>().oneOf(SUPPORTED_AD_BANNER_PROVIDERS),
|
|
NEXT_PUBLIC_AD_BANNER_ADDITIONAL_PROVIDER: yup.string<AdBannerAdditionalProviders>().oneOf(SUPPORTED_AD_BANNER_ADDITIONAL_PROVIDERS),
|
|
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_DESKTOP: adButlerConfigSchema,
|
|
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE: adButlerConfigSchema,
|
|
});
|
|
|
|
const sentrySchema = yup
|
|
.object()
|
|
.shape({
|
|
NEXT_PUBLIC_SENTRY_DSN: yup.string().test(urlTest),
|
|
SENTRY_CSP_REPORT_URI: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_SENTRY_DSN', {
|
|
is: (value: string) => Boolean(value),
|
|
then: (schema) => schema.test(urlTest),
|
|
otherwise: (schema) => schema.max(-1, 'SENTRY_CSP_REPORT_URI cannot not be used without NEXT_PUBLIC_SENTRY_DSN'),
|
|
}),
|
|
NEXT_PUBLIC_SENTRY_ENABLE_TRACING: yup
|
|
.boolean()
|
|
.when('NEXT_PUBLIC_SENTRY_DSN', {
|
|
is: (value: string) => Boolean(value),
|
|
then: (schema) => schema,
|
|
}),
|
|
NEXT_PUBLIC_APP_INSTANCE: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_SENTRY_DSN', {
|
|
is: (value: string) => Boolean(value),
|
|
then: (schema) => schema,
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_APP_INSTANCE cannot not be used without NEXT_PUBLIC_SENTRY_DSN'),
|
|
}),
|
|
NEXT_PUBLIC_APP_ENV: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_SENTRY_DSN', {
|
|
is: (value: string) => Boolean(value),
|
|
then: (schema) => schema,
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_APP_ENV cannot not be used without NEXT_PUBLIC_SENTRY_DSN'),
|
|
}),
|
|
});
|
|
|
|
const accountSchema = yup
|
|
.object()
|
|
.shape({
|
|
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED: yup.boolean(),
|
|
NEXT_PUBLIC_AUTH0_CLIENT_ID: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED', {
|
|
is: (value: boolean) => value,
|
|
then: (schema) => schema.required(),
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_AUTH0_CLIENT_ID cannot not be used if NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED is not set to "true"'),
|
|
}),
|
|
NEXT_PUBLIC_AUTH_URL: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED', {
|
|
is: (value: boolean) => value,
|
|
then: (schema) => schema.test(urlTest),
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_AUTH_URL cannot not be used if NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED is not set to "true"'),
|
|
}),
|
|
NEXT_PUBLIC_LOGOUT_URL: yup
|
|
.string()
|
|
.when('NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED', {
|
|
is: (value: boolean) => value,
|
|
then: (schema) => schema.test(urlTest).required(),
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_LOGOUT_URL cannot not be used if NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED is not set to "true"'),
|
|
}),
|
|
});
|
|
|
|
const featuredNetworkSchema: yup.ObjectSchema<FeaturedNetwork> = yup
|
|
.object()
|
|
.shape({
|
|
title: yup.string().required(),
|
|
url: yup.string().test(urlTest).required(),
|
|
group: yup.string().oneOf(NETWORK_GROUPS).required(),
|
|
icon: yup.string().test(urlTest),
|
|
isActive: yup.boolean(),
|
|
invertIconInDarkMode: yup.boolean(),
|
|
});
|
|
|
|
const navItemExternalSchema: yup.ObjectSchema<NavItemExternal> = yup
|
|
.object({
|
|
text: yup.string().required(),
|
|
url: yup.string().test(urlTest).required(),
|
|
});
|
|
|
|
const footerLinkSchema: yup.ObjectSchema<CustomLink> = yup
|
|
.object({
|
|
text: yup.string().required(),
|
|
url: yup.string().test(urlTest).required(),
|
|
});
|
|
|
|
const footerLinkGroupSchema: yup.ObjectSchema<CustomLinksGroup> = yup
|
|
.object({
|
|
title: yup.string().required(),
|
|
links: yup
|
|
.array()
|
|
.of(footerLinkSchema)
|
|
.required(),
|
|
});
|
|
|
|
const networkExplorerSchema: yup.ObjectSchema<NetworkExplorer> = yup
|
|
.object({
|
|
title: yup.string().required(),
|
|
logo: yup.string().test(urlTest),
|
|
baseUrl: yup.string().test(urlTest).required(),
|
|
paths: yup
|
|
.object()
|
|
.shape({
|
|
tx: yup.string(),
|
|
address: yup.string(),
|
|
token: yup.string(),
|
|
block: yup.string(),
|
|
}),
|
|
});
|
|
|
|
const contractCodeIdeSchema: yup.ObjectSchema<ContractCodeIde> = yup
|
|
.object({
|
|
title: yup.string().required(),
|
|
url: yup.string().test(urlTest).required(),
|
|
icon_url: yup.string().test(urlTest).required(),
|
|
});
|
|
|
|
const nftMarketplaceSchema: yup.ObjectSchema<NftMarketplaceItem> = yup
|
|
.object({
|
|
name: yup.string().required(),
|
|
collection_url: yup.string().test(urlTest).required(),
|
|
instance_url: yup.string().test(urlTest).required(),
|
|
logo_url: yup.string().test(urlTest).required(),
|
|
});
|
|
|
|
const bridgedTokenChainSchema: yup.ObjectSchema<BridgedTokenChain> = yup
|
|
.object({
|
|
id: yup.string().required(),
|
|
title: yup.string().required(),
|
|
short_title: yup.string().required(),
|
|
base_url: yup.string().test(urlTest).required(),
|
|
});
|
|
|
|
const tokenBridgeSchema: yup.ObjectSchema<TokenBridge> = yup
|
|
.object({
|
|
type: yup.string().required(),
|
|
title: yup.string().required(),
|
|
short_title: yup.string().required(),
|
|
});
|
|
|
|
const bridgedTokensSchema = yup
|
|
.object()
|
|
.shape({
|
|
NEXT_PUBLIC_BRIDGED_TOKENS_CHAINS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(bridgedTokenChainSchema),
|
|
NEXT_PUBLIC_BRIDGED_TOKENS_BRIDGES: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(tokenBridgeSchema)
|
|
.when('NEXT_PUBLIC_BRIDGED_TOKENS_CHAINS', {
|
|
is: (value: Array<unknown>) => value && value.length > 0,
|
|
then: (schema) => schema.required(),
|
|
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_BRIDGED_TOKENS_BRIDGES cannot not be used without NEXT_PUBLIC_BRIDGED_TOKENS_CHAINS'),
|
|
}),
|
|
});
|
|
|
|
const deFiDropdownItemSchema: yup.ObjectSchema<DeFiDropdownItem> = yup
|
|
.object({
|
|
text: yup.string().required(),
|
|
icon: yup.string<IconName>().required(),
|
|
dappId: yup.string(),
|
|
url: yup.string().test(urlTest),
|
|
})
|
|
.test('oneOfRequired', 'NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS: Either dappId or url is required', function(value) {
|
|
return Boolean(value.dappId) || Boolean(value.url);
|
|
}) as yup.ObjectSchema<DeFiDropdownItem>;
|
|
|
|
const schema = yup
|
|
.object()
|
|
.noUnknown(true, (params) => {
|
|
return `Unknown ENV variables were provided: ${ params.unknown }`;
|
|
})
|
|
.shape({
|
|
// I. Build-time ENVs
|
|
// -----------------
|
|
NEXT_PUBLIC_GIT_TAG: yup.string(),
|
|
NEXT_PUBLIC_GIT_COMMIT_SHA: yup.string(),
|
|
|
|
// II. Run-time ENVs
|
|
// -----------------
|
|
// 1. App configuration
|
|
NEXT_PUBLIC_APP_HOST: yup.string().required(),
|
|
NEXT_PUBLIC_APP_PROTOCOL: yup.string().oneOf(protocols),
|
|
NEXT_PUBLIC_APP_PORT: yup.number().positive().integer(),
|
|
|
|
// 2. Blockchain parameters
|
|
NEXT_PUBLIC_NETWORK_NAME: yup.string().required(),
|
|
NEXT_PUBLIC_NETWORK_SHORT_NAME: yup.string(),
|
|
NEXT_PUBLIC_NETWORK_ID: yup.number().positive().integer().required(),
|
|
NEXT_PUBLIC_NETWORK_RPC_URL: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_NAME: yup.string(),
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_WEI_NAME: yup.string(),
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL: yup.string(),
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS: yup.number().integer().positive(),
|
|
NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL: yup.string(),
|
|
NEXT_PUBLIC_NETWORK_MULTIPLE_GAS_CURRENCIES: yup.boolean(),
|
|
NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE: yup.string<NetworkVerificationType>().oneOf([ 'validation', 'mining' ]),
|
|
NEXT_PUBLIC_NETWORK_TOKEN_STANDARD_NAME: yup.string(),
|
|
NEXT_PUBLIC_IS_TESTNET: yup.boolean(),
|
|
|
|
// 3. API configuration
|
|
NEXT_PUBLIC_API_PROTOCOL: yup.string().oneOf(protocols),
|
|
NEXT_PUBLIC_API_HOST: yup.string().required(),
|
|
NEXT_PUBLIC_API_PORT: yup.number().integer().positive(),
|
|
NEXT_PUBLIC_API_BASE_PATH: yup.string(),
|
|
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL: yup.string().oneOf([ 'ws', 'wss' ]),
|
|
|
|
// 4. UI configuration
|
|
// a. homepage
|
|
NEXT_PUBLIC_HOMEPAGE_CHARTS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(yup.string<ChainIndicatorId>().oneOf(CHAIN_INDICATOR_IDS)),
|
|
NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR: yup.string(),
|
|
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND: yup.string(),
|
|
NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME: yup.boolean(),
|
|
|
|
// b. sidebar
|
|
NEXT_PUBLIC_FEATURED_NETWORKS: yup
|
|
.array()
|
|
.json()
|
|
.of(featuredNetworkSchema),
|
|
NEXT_PUBLIC_OTHER_LINKS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(navItemExternalSchema),
|
|
NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(yup.string<NavigationLinkId>().oneOf(NAVIGATION_LINK_IDS)),
|
|
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(yup.string()),
|
|
NEXT_PUBLIC_NAVIGATION_LAYOUT: yup.string<NavigationLayout>().oneOf([ 'horizontal', 'vertical' ]),
|
|
NEXT_PUBLIC_NETWORK_LOGO: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_NETWORK_LOGO_DARK: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_NETWORK_ICON: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_NETWORK_ICON_DARK: yup.string().test(urlTest),
|
|
|
|
// c. footer
|
|
NEXT_PUBLIC_FOOTER_LINKS: yup
|
|
.array()
|
|
.json()
|
|
.of(footerLinkGroupSchema),
|
|
|
|
// d. views
|
|
NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(yup.string<BlockFieldId>().oneOf(BLOCK_FIELDS_IDS)),
|
|
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE: yup.string().oneOf(IDENTICON_TYPES),
|
|
NEXT_PUBLIC_VIEWS_ADDRESS_HIDDEN_VIEWS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(yup.string<AddressViewId>().oneOf(ADDRESS_VIEWS_IDS)),
|
|
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED: yup.boolean(),
|
|
NEXT_PUBLIC_VIEWS_TX_HIDDEN_FIELDS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(yup.string<TxFieldsId>().oneOf(TX_FIELDS_IDS)),
|
|
NEXT_PUBLIC_VIEWS_TX_ADDITIONAL_FIELDS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(yup.string<TxAdditionalFieldsId>().oneOf(TX_ADDITIONAL_FIELDS_IDS)),
|
|
NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(nftMarketplaceSchema),
|
|
|
|
// e. misc
|
|
NEXT_PUBLIC_NETWORK_EXPLORERS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(networkExplorerSchema),
|
|
NEXT_PUBLIC_CONTRACT_CODE_IDES: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(contractCodeIdeSchema),
|
|
NEXT_PUBLIC_HAS_CONTRACT_AUDIT_REPORTS: yup.boolean(),
|
|
NEXT_PUBLIC_HIDE_INDEXING_ALERT_BLOCKS: yup.boolean(),
|
|
NEXT_PUBLIC_HIDE_INDEXING_ALERT_INT_TXS: yup.boolean(),
|
|
NEXT_PUBLIC_MAINTENANCE_ALERT_MESSAGE: yup.string(),
|
|
NEXT_PUBLIC_COLOR_THEME_DEFAULT: yup.string().oneOf(COLOR_THEME_IDS),
|
|
|
|
// 5. Features configuration
|
|
NEXT_PUBLIC_API_SPEC_URL: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_STATS_API_HOST: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_STATS_API_BASE_PATH: yup.string(),
|
|
NEXT_PUBLIC_VISUALIZE_API_HOST: yup.string().test(urlTest),
|
|
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_METADATA_SERVICE_API_HOST: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_GRAPHIQL_TRANSACTION: yup.string().matches(regexp.HEX_REGEXP),
|
|
NEXT_PUBLIC_WEB3_WALLETS: yup
|
|
.mixed()
|
|
.test('shape', 'Invalid schema were provided for NEXT_PUBLIC_WEB3_WALLETS, it should be either array or "none" string literal', (data) => {
|
|
const isNoneSchema = yup.string().equals([ 'none' ]);
|
|
const isArrayOfWalletsSchema = yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(yup.string<WalletType>().oneOf(SUPPORTED_WALLETS));
|
|
|
|
return isNoneSchema.isValidSync(data) || isArrayOfWalletsSchema.isValidSync(data);
|
|
}),
|
|
NEXT_PUBLIC_WEB3_DISABLE_ADD_TOKEN_TO_WALLET: yup.boolean(),
|
|
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER: yup.string().oneOf(TX_INTERPRETATION_PROVIDERS),
|
|
NEXT_PUBLIC_AD_TEXT_PROVIDER: yup.string<AdTextProviders>().oneOf(SUPPORTED_AD_TEXT_PROVIDERS),
|
|
NEXT_PUBLIC_PROMOTE_BLOCKSCOUT_IN_TITLE: yup.boolean(),
|
|
NEXT_PUBLIC_OG_DESCRIPTION: yup.string(),
|
|
NEXT_PUBLIC_OG_IMAGE_URL: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED: yup.boolean(),
|
|
NEXT_PUBLIC_SEO_ENHANCED_DATA_ENABLED: yup.boolean(),
|
|
NEXT_PUBLIC_SAFE_TX_SERVICE_URL: yup.string().test(urlTest),
|
|
NEXT_PUBLIC_IS_SUAVE_CHAIN: yup.boolean(),
|
|
NEXT_PUBLIC_HAS_USER_OPS: yup.boolean(),
|
|
NEXT_PUBLIC_METASUITES_ENABLED: yup.boolean(),
|
|
NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG: yup
|
|
.mixed()
|
|
.test('shape', 'Invalid schema were provided for NEXT_PUBLIC_MULTICHAIN_BALANCE_PROVIDER_CONFIG, it should have name and url template', (data) => {
|
|
const isUndefined = data === undefined;
|
|
const valueSchema = yup.object<MultichainProviderConfig>().transform(replaceQuotes).json().shape({
|
|
name: yup.string().required(),
|
|
url_template: yup.string().required(),
|
|
logo: yup.string(),
|
|
dapp_id: yup.string(),
|
|
});
|
|
|
|
return isUndefined || valueSchema.isValidSync(data);
|
|
}),
|
|
NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE: yup.string<ValidatorsChainType>().oneOf(VALIDATORS_CHAIN_TYPE),
|
|
NEXT_PUBLIC_GAS_TRACKER_ENABLED: yup.boolean(),
|
|
NEXT_PUBLIC_GAS_TRACKER_UNITS: yup.array().transform(replaceQuotes).json().of(yup.string<GasUnit>().oneOf(GAS_UNITS)),
|
|
NEXT_PUBLIC_DATA_AVAILABILITY_ENABLED: yup.boolean(),
|
|
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS: yup
|
|
.array()
|
|
.transform(replaceQuotes)
|
|
.json()
|
|
.of(deFiDropdownItemSchema),
|
|
NEXT_PUBLIC_FAULT_PROOF_ENABLED: yup.boolean()
|
|
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
|
|
is: 'optimistic',
|
|
then: (schema) => schema,
|
|
otherwise: (schema) => schema.test(
|
|
'not-exist',
|
|
'NEXT_PUBLIC_FAULT_PROOF_ENABLED can only be used with NEXT_PUBLIC_ROLLUP_TYPE=optimistic',
|
|
value => value === undefined,
|
|
),
|
|
}),
|
|
|
|
// 6. External services envs
|
|
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: yup.string(),
|
|
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY: yup.string(),
|
|
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: yup.string(),
|
|
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN: yup.string(),
|
|
NEXT_PUBLIC_GROWTH_BOOK_CLIENT_KEY: yup.string(),
|
|
|
|
// Misc
|
|
NEXT_PUBLIC_USE_NEXT_JS_PROXY: yup.boolean(),
|
|
})
|
|
.concat(accountSchema)
|
|
.concat(adsBannerSchema)
|
|
.concat(marketplaceSchema)
|
|
.concat(rollupSchema)
|
|
.concat(beaconChainSchema)
|
|
.concat(bridgedTokensSchema)
|
|
.concat(sentrySchema);
|
|
|
|
export default schema;
|