Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions configs/app/api.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import stripTrailingSlash from 'lib/stripTrailingSlash';

import { getEnvValue } from './utils';
import { getApiHost, getEnvValue } from './utils';

const apiHost = getEnvValue('NEXT_PUBLIC_API_HOST');
const apiHost = getApiHost();
const apiSchema = getEnvValue('NEXT_PUBLIC_API_PROTOCOL') || 'https';
const apiPort = getEnvValue('NEXT_PUBLIC_API_PORT');
const apiEndpoint = [
Expand Down
111 changes: 85 additions & 26 deletions configs/app/chain.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import {
DEVNET_NETWORK_NATIVE_CURRENCY,
FLUENT_DEVNET_CHAIN_ID,
DEVNET_RPC_URL,
} from '@fluent.xyz/sdk-core/dist/config/devnet-config';
import {
TESTNET_NETWORK_NATIVE_CURRENCY,
FLUENT_TESTNET_CHAIN_ID,
TESTNET_RPC_URL,
} from '@fluent.xyz/sdk-core/dist/config/testnet-config';

import type { RollupType } from 'types/client/rollup';
import type { NetworkVerificationType, NetworkVerificationTypeEnvs } from 'types/networks';

import { urlValidator } from 'ui/shared/forms/validators/url';

import { getEnvValue, parseEnvJson } from './utils';

const DEFAULT_CURRENCY_DECIMALS = 18;

const rollupType = getEnvValue('NEXT_PUBLIC_ROLLUP_TYPE') as RollupType;

const verificationType: NetworkVerificationType = (() => {
Expand All @@ -20,36 +29,86 @@ const verificationType: NetworkVerificationType = (() => {
})();

const rpcUrls = (() => {
const envValue = getEnvValue('NEXT_PUBLIC_NETWORK_RPC_URL');
const isUrl = urlValidator(envValue);
const env = getEnvValue('NEXT_PUBLIC_CHAIN');
const value = env === 'devnet' ? DEVNET_RPC_URL : TESTNET_RPC_URL;
const isUrl = urlValidator(value);

if (envValue && isUrl === true) {
return [ envValue ];
if (value && isUrl === true) {
return [ value ];
}

const parsedValue = parseEnvJson<Array<string>>(envValue);
const parsedValue = parseEnvJson<Array<string>>(value);

return Array.isArray(parsedValue) ? parsedValue : [];
})();

const chain = Object.freeze({
id: getEnvValue('NEXT_PUBLIC_NETWORK_ID'),
name: getEnvValue('NEXT_PUBLIC_NETWORK_NAME'),
shortName: getEnvValue('NEXT_PUBLIC_NETWORK_SHORT_NAME'),
currency: {
name: getEnvValue('NEXT_PUBLIC_NETWORK_CURRENCY_NAME'),
weiName: getEnvValue('NEXT_PUBLIC_NETWORK_CURRENCY_WEI_NAME'),
symbol: getEnvValue('NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL'),
decimals: Number(getEnvValue('NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS')) || DEFAULT_CURRENCY_DECIMALS,
},
secondaryCoin: {
symbol: getEnvValue('NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL'),
},
hasMultipleGasCurrencies: getEnvValue('NEXT_PUBLIC_NETWORK_MULTIPLE_GAS_CURRENCIES') === 'true',
tokenStandard: getEnvValue('NEXT_PUBLIC_NETWORK_TOKEN_STANDARD_NAME') || 'ERC',
rpcUrls,
isTestnet: getEnvValue('NEXT_PUBLIC_IS_TESTNET') === 'true',
verificationType,
});
const getChain = () => {
const env = getEnvValue('NEXT_PUBLIC_CHAIN');

switch (env) {
case 'develop':
return {
id: String(parseInt(String(FLUENT_DEVNET_CHAIN_ID), 16)),
name: 'Fluent',
shortName: 'Fluent',
currency: {
name: DEVNET_NETWORK_NATIVE_CURRENCY.name,
weiName: getEnvValue('NEXT_PUBLIC_NETWORK_CURRENCY_WEI_NAME'),
symbol: DEVNET_NETWORK_NATIVE_CURRENCY.symbol,
decimals: DEVNET_NETWORK_NATIVE_CURRENCY.decimals,
},
secondaryCoin: {
symbol: getEnvValue('NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL'),
},
hasMultipleGasCurrencies: false,
tokenStandard: 'ERC',
rpcUrls,
isTestnet: true,
verificationType,
};
case 'testnet':
return {
id: String(parseInt(String(FLUENT_TESTNET_CHAIN_ID), 16)),
name: 'Fluent',
shortName: 'Fluent',
currency: {
name: TESTNET_NETWORK_NATIVE_CURRENCY.name,
weiName: getEnvValue('NEXT_PUBLIC_NETWORK_CURRENCY_WEI_NAME'),
symbol: TESTNET_NETWORK_NATIVE_CURRENCY.symbol,
decimals: TESTNET_NETWORK_NATIVE_CURRENCY.decimals,
},
secondaryCoin: {
symbol: getEnvValue('NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL'),
},
hasMultipleGasCurrencies: false,
tokenStandard: 'ERC',
rpcUrls,
isTestnet: true,
verificationType,
};
default:
return {
id: String(parseInt(String(FLUENT_DEVNET_CHAIN_ID), 16)),
name: 'Fluent',
shortName: 'Fluent',
currency: {
name: DEVNET_NETWORK_NATIVE_CURRENCY.name,
weiName: getEnvValue('NEXT_PUBLIC_NETWORK_CURRENCY_WEI_NAME'),
symbol: DEVNET_NETWORK_NATIVE_CURRENCY.symbol,
decimals: DEVNET_NETWORK_NATIVE_CURRENCY.decimals,
},
secondaryCoin: {
symbol: getEnvValue('NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL'),
},
hasMultipleGasCurrencies: false,
tokenStandard: 'ERC',
rpcUrls,
isTestnet: true,
verificationType,
};
}
};

const chain = Object.freeze(getChain());

export default chain;
4 changes: 2 additions & 2 deletions configs/app/features/beaconChain.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Feature } from './types';

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

const title = 'Beacon chain';
Expand All @@ -11,8 +12,7 @@ const config: Feature<{ currency: { symbol: string } }> = (() => {
isEnabled: true,
currency: {
symbol:
getEnvValue('NEXT_PUBLIC_BEACON_CHAIN_CURRENCY_SYMBOL') ||
getEnvValue('NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL') ||
chain.currency.symbol ||
'', // maybe we need some other default value here
},
});
Expand Down
4 changes: 2 additions & 2 deletions configs/app/features/sol2uml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { Feature } from './types';

import stripTrailingSlash from 'lib/stripTrailingSlash';

import { getEnvValue } from '../utils';
import { getEnvValue, getVisualizeApiHost } from '../utils';

const apiEndpoint = getEnvValue('NEXT_PUBLIC_VISUALIZE_API_HOST');
const apiEndpoint = getVisualizeApiHost();

const title = 'Solidity to UML diagrams';

Expand Down
4 changes: 2 additions & 2 deletions configs/app/features/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { Feature } from './types';

import stripTrailingSlash from 'lib/stripTrailingSlash';

import { getEnvValue } from '../utils';
import { getEnvValue, getStatsApiHost } from '../utils';

const apiEndpoint = getEnvValue('NEXT_PUBLIC_STATS_API_HOST');
const apiEndpoint = getStatsApiHost();

const title = 'Blockchain statistics';

Expand Down
43 changes: 37 additions & 6 deletions configs/app/utils.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,54 @@
import { DEVNET_EXPLORER_HOST, DEVNET_EXPLORER_URL } from '@fluent.xyz/sdk-core/dist/config/devnet-config';
import { TESTNET_EXPLORER_HOST, TESTNET_EXPLORER_URL } from '@fluent.xyz/sdk-core/dist/config/testnet-config';

import isBrowser from 'lib/isBrowser';
import * as regexp from 'lib/regexp';

export const replaceQuotes = (value: string | undefined) => value?.replaceAll('\'', '"');

export const getEnvValue = (envName: string) => {
// eslint-disable-next-line no-restricted-properties
const envs = (isBrowser() ? window.__envs : process.env) ?? {};
let envs: Record<string, string | undefined> = {};

if (isBrowser()) {

if (isBrowser() && envs.NEXT_PUBLIC_APP_INSTANCE === 'pw') {
const storageValue = localStorage.getItem(envName);
const windowEnvs = (window as unknown as { __envs?: Record<string, string | undefined> }).__envs;
envs = windowEnvs ?? {};

if (typeof storageValue === 'string') {
return storageValue;
if (envs.NEXT_PUBLIC_APP_INSTANCE === 'pw') {
const storageValue = localStorage.getItem(envName);
if (typeof storageValue === 'string') {
return storageValue;
}
}
} else {
// eslint-disable-next-line no-restricted-properties
envs = process.env as unknown as Record<string, string | undefined>;
}

return replaceQuotes(envs[envName]);
};

export const getApiHost = () => {
const env = getEnvValue('NEXT_PUBLIC_CHAIN');
const value = env === 'devnet' ? DEVNET_EXPLORER_HOST : TESTNET_EXPLORER_HOST;

return value;
};

export const getStatsApiHost = () => {
const env = getEnvValue('NEXT_PUBLIC_CHAIN');
const value = env === 'devnet' ? DEVNET_EXPLORER_URL : TESTNET_EXPLORER_URL;

return value + ':8080';
};

export const getVisualizeApiHost = () => {
const env = getEnvValue('NEXT_PUBLIC_CHAIN');
const value = env === 'devnet' ? DEVNET_EXPLORER_URL : TESTNET_EXPLORER_URL;

return value + ':8081';
};

export const parseEnvJson = <DataType>(env: string | undefined): DataType | null => {
try {
return JSON.parse(env || 'null') as DataType | null;
Expand Down
20 changes: 20 additions & 0 deletions decs.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
declare module 'react-identicons'

declare module '@fluent.xyz/sdk-core/dist/config/devnet-config' {
export const DEVNET_NETWORK: string;
export const DEVNET_NETWORK_NATIVE_CURRENCY: { name: string; symbol: string; decimals: number };
export const DEVNET_EXPLORER_NAME: string;
export const FLUENT_DEVNET_CHAIN_ID: number;
export const DEVNET_EXPLORER_HOST: string;
export const DEVNET_EXPLORER_URL: string;
export const DEVNET_RPC_URL: string;
}

declare module '@fluent.xyz/sdk-core/dist/config/testnet-config' {
export const TESTNET_NETWORK: string;
export const TESTNET_NETWORK_NATIVE_CURRENCY: { name: string; symbol: string; decimals: number };
export const TESTNET_EXPLORER_NAME: string;
export const FLUENT_TESTNET_CHAIN_ID: number;
export const TESTNET_EXPLORER_HOST: string;
export const TESTNET_EXPLORER_URL: string;
export const TESTNET_RPC_URL: string;
}
5 changes: 1 addition & 4 deletions deploy/scripts/og_image_generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,14 @@ function copyPlaceholderImage() {

if (process.env.NEXT_PUBLIC_OG_IMAGE_URL) {
console.log('⏩ NEXT_PUBLIC_OG_IMAGE_URL is set. Skipping OG image generation...');
} else if (!process.env.NEXT_PUBLIC_NETWORK_NAME) {
console.log('⏩ NEXT_PUBLIC_NETWORK_NAME is not set. Copying placeholder image...');
copyPlaceholderImage();
} else if (!process.env.NEXT_PUBLIC_NETWORK_LOGO && !process.env.NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG) {
console.log('⏩ Neither NEXT_PUBLIC_NETWORK_LOGO nor NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG is set. Copying placeholder image...');
copyPlaceholderImage();
} else {
try {
const bannerConfig = JSON.parse(process.env.NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG?.replaceAll('\'', '"') || '{}');
const data = {
title: `${ process.env.NEXT_PUBLIC_NETWORK_NAME } explorer`,
title: `Fluent explorer`,
logo_url: process.env.NEXT_PUBLIC_NETWORK_LOGO_DARK ?? process.env.NEXT_PUBLIC_NETWORK_LOGO,
background: bannerConfig.background?.[0],
title_color: bannerConfig.text_color?.[0],
Expand Down
2 changes: 1 addition & 1 deletion deploy/scripts/sitemap_generator.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
cd ./deploy/tools/sitemap-generator
yarn next-sitemap
yarn next-sitemap --config next-sitemap.config.mjs
11 changes: 6 additions & 5 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -584,9 +584,10 @@ const schema = yup
NEXT_PUBLIC_APP_INSTANCE: yup.string(),

// 2. Blockchain parameters
NEXT_PUBLIC_NETWORK_NAME: yup.string().required(),
NEXT_PUBLIC_CHAIN: yup.string().required(),
NEXT_PUBLIC_NETWORK_NAME: yup.string(),
NEXT_PUBLIC_NETWORK_SHORT_NAME: yup.string(),
NEXT_PUBLIC_NETWORK_ID: yup.number().positive().integer().required(),
NEXT_PUBLIC_NETWORK_ID: yup.number().positive().integer(),
NEXT_PUBLIC_NETWORK_RPC_URL: yup
.mixed()
.test(
Expand Down Expand Up @@ -624,7 +625,7 @@ const schema = yup

// 3. API configuration
NEXT_PUBLIC_API_PROTOCOL: yup.string().oneOf(protocols),
NEXT_PUBLIC_API_HOST: yup.string().required(),
NEXT_PUBLIC_API_HOST: yup.string(),
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' ]),
Expand Down Expand Up @@ -796,9 +797,9 @@ const schema = yup

return isNoneSchema.isValidSync(data) || isUrlStringSchema.isValidSync(data);
}),
NEXT_PUBLIC_STATS_API_HOST: yup.string().test(urlTest),
NEXT_PUBLIC_STATS_API_HOST: yup.string(),
NEXT_PUBLIC_STATS_API_BASE_PATH: yup.string(),
NEXT_PUBLIC_VISUALIZE_API_HOST: yup.string().test(urlTest),
NEXT_PUBLIC_VISUALIZE_API_HOST: yup.string(),
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),
Expand Down
1 change: 1 addition & 0 deletions deploy/tools/envs-validator/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"../../../types/**/*.ts",
"../../../configs/app/**/*.ts",
"../../../global.d.ts",
"../../../decs.d.ts",
"./index.ts",
"./schema.ts"
],
Expand Down
2 changes: 1 addition & 1 deletion deploy/tools/feature-reporter/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"nextjs-routes": ["./nextjs/nextjs-routes.d.ts"],
}
},
"include": [ "../../../configs/app/index.ts", "../../../global.d.ts" ],
"include": [ "../../../configs/app/index.ts", "../../../global.d.ts", "../../../decs.d.ts" ],
"tsc-alias": {
"verbose": true,
"resolveFullPaths": true,
Expand Down
Loading
Loading