Skip to content
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

Develop to Goerli #123

Merged
merged 16 commits into from
Nov 9, 2023
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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# EL_RPC_URLS_{CHAIN_ID} list or URLs delimeted by commas, first entry is primary, else are fallbacks
# EL_RPC_URLS_{CHAIN_ID} list or URLs delimeted by commas, first entry is primary, else are fallbacks
EL_RPC_URLS_1=
EL_RPC_URLS_5=
EL_RPC_URLS_17000=
Expand Down
26 changes: 1 addition & 25 deletions assets/icons/l2-swap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import NextBundleAnalyzer from '@next/bundle-analyzer';
import buildDynamics from './scripts/build-dynamics.mjs';
import generateBuildId from './scripts/generate-build-id.mjs';

buildDynamics();

Expand Down Expand Up @@ -55,6 +56,7 @@ const withBundleAnalyzer = NextBundleAnalyzer({

export default withBundleAnalyzer({
basePath,
generateBuildId,
eslint: {
ignoreDuringBuilds: true,
},
Expand Down
65 changes: 54 additions & 11 deletions pages/api/oneinch-rate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { BigNumber } from 'ethers';
import { Cache } from 'memory-cache';
import { NextApiRequest, NextApiResponse } from 'next';

import { wrapRequest as wrapNextRequest } from '@lidofinance/next-api-wrapper';
import { CHAINS, TOKENS, getTokenAddress } from '@lido-sdk/constants';

import {
CACHE_ONE_INCH_RATE_KEY,
CACHE_ONE_INCH_RATE_TTL,
Expand All @@ -11,39 +15,78 @@ import {
responseTimeMetric,
errorAndCacheDefaultWrappers,
rateLimit,
httpMethodGuard,
HttpMethod,
cors,
} from 'utilsApi';
import Metrics from 'utilsApi/metrics';
import { API } from 'types';
import { BigNumber } from 'ethers';

const cache = new Cache<typeof CACHE_ONE_INCH_RATE_KEY, unknown>();
const cache = new Cache<string, unknown>();

const DEFAULT_AMOUNT = BigNumber.from(10).pow(18);
const TOKEN_ETH = 'ETH';
const TOKEN_ALLOWED_LIST = [TOKEN_ETH, TOKENS.STETH, TOKENS.WSTETH];

const validateAndGetQueryToken = async (
req: NextApiRequest,
res: NextApiResponse,
): Promise<string> => {
let token = req.query?.token || TOKEN_ETH;

// Token can be array - /api/oneinch-rate/?token=eth&token=eth&token=eth
if (Array.isArray(token)) {
token = token[0];
}

token = token.toLocaleUpperCase();

if (!TOKEN_ALLOWED_LIST.includes(token)) {
res.status(400);
throw new Error(`You can use only: ${TOKEN_ALLOWED_LIST.toString()}`);
}

return token;
};

// Proxy for third-party API.
// Query params:
// * (optional) token: see TOKEN_ALLOWED_LIST above. Default see TOKEN_ETH above.
// Returns 1inch rate
const oneInchRate: API = async (req, res) => {
const cachedOneInchRate = cache.get(CACHE_ONE_INCH_RATE_KEY);
const token = await validateAndGetQueryToken(req, res);
const cacheKey = `${CACHE_ONE_INCH_RATE_KEY}-${token}`;
const cachedOneInchRate = cache.get(cacheKey);

if (cachedOneInchRate) {
res.status(200).json(cachedOneInchRate);
} else {
const oneInchRate = await getOneInchRate(
return;
}

// Execute below if not found a cache
let oneInchRate;

if (token === TOKEN_ETH) {
oneInchRate = await getOneInchRate(
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
getTokenAddress(CHAINS.Mainnet, TOKENS.STETH),
DEFAULT_AMOUNT,
);
cache.put(
CACHE_ONE_INCH_RATE_KEY,
{ rate: oneInchRate },
CACHE_ONE_INCH_RATE_TTL,
} else {
oneInchRate = await getOneInchRate(
getTokenAddress(CHAINS.Mainnet, token as TOKENS),
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
DEFAULT_AMOUNT,
);

res.status(200).json({ rate: oneInchRate });
}
cache.put(cacheKey, { rate: oneInchRate }, CACHE_ONE_INCH_RATE_TTL);

res.status(200).json({ rate: oneInchRate });
};

export default wrapNextRequest([
httpMethodGuard([HttpMethod.GET]),
cors({ origin: ['*'], methods: [HttpMethod.GET] }),
rateLimit,
responseTimeMetric(Metrics.request.apiTimings, API_ROUTES.ONEINCH_RATE),
...errorAndCacheDefaultWrappers,
Expand Down
16 changes: 11 additions & 5 deletions pages/api/short-lido-stats.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import getConfig from 'next/config';
import { Cache } from 'memory-cache';
import { wrapRequest as wrapNextRequest } from '@lidofinance/next-api-wrapper';

import {
API_ROUTES,
CACHE_LIDO_SHORT_STATS_KEY,
CACHE_LIDO_SHORT_STATS_TTL,
API_ROUTES,
} from 'config';
import { API, SubgraphChains } from 'types';
import {
getTotalStaked,
cors,
errorAndCacheDefaultWrappers,
getLidoHoldersViaSubgraphs,
getStEthPrice,
errorAndCacheDefaultWrappers,
responseTimeMetric,
getTotalStaked,
HttpMethod,
httpMethodGuard,
rateLimit,
responseTimeMetric,
} from 'utilsApi';
import Metrics from 'utilsApi/metrics';
import { API, SubgraphChains } from 'types';
import { parallelizePromises } from 'utils';

const { serverRuntimeConfig } = getConfig();
Expand Down Expand Up @@ -57,6 +61,8 @@ const shortLidoStats: API = async (req, res) => {
};

export default wrapNextRequest([
httpMethodGuard([HttpMethod.GET]),
cors({ origin: ['*'], methods: [HttpMethod.GET] }),
rateLimit,
responseTimeMetric(Metrics.request.apiTimings, API_ROUTES.SHORT_LIDO_STATS),
...errorAndCacheDefaultWrappers,
Expand Down
10 changes: 10 additions & 0 deletions scripts/generate-build-id.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import buildInfo from '../build-info.json' assert { type: 'json' };

export default function generateBuildId() {
const commit = buildInfo.commit;
const buildId = commit === 'REPLACE_WITH_COMMIT' ? null : commit;
console.info(
buildId ? `Generated build id: ${buildId}` : 'Fallback to default build ID',
);
return buildId;
}
1 change: 1 addition & 0 deletions shared/banners/l2-banner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './l2-banner';
60 changes: 60 additions & 0 deletions shared/banners/l2-banner/l2-banner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { ThemeProvider, themeDark } from '@lidofinance/lido-ui';

import {
Wrapper,
L2Icons,
TextWrap,
ButtonWrap,
ButtonLinkWrap,
ButtonStyle,
ContentWrap,
TextHeader,
} from './styles';

type L2BannerProps = {
title: React.ReactNode;
text: React.ReactNode;
buttonText: React.ReactNode;
buttonHref: string;
testidWrap: string;
testidButton: string;
onClickButton?: () => void;
};

export const L2Banner = ({
title,
text,
buttonText,
buttonHref,
testidWrap,
testidButton,
onClickButton,
}: L2BannerProps) => {
return (
<Wrapper data-testid={testidWrap}>
<ThemeProvider theme={themeDark}>
<ContentWrap>
<TextHeader>{title}</TextHeader>
<TextWrap>{text}</TextWrap>
<ButtonWrap>
<ButtonLinkWrap
href={buttonHref}
target="_blank"
rel="noopener noreferrer"
onClick={onClickButton}
>
<ButtonStyle
data-testid={testidButton}
size="sm"
color="secondary"
>
{buttonText}
</ButtonStyle>
</ButtonLinkWrap>
</ButtonWrap>
</ContentWrap>
<L2Icons />
</ThemeProvider>
</Wrapper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,25 @@ import { Button } from '@lidofinance/lido-ui';
import Icons from 'assets/icons/l2-swap.svg';

export const Wrapper = styled.div`
text-align: left;
margin-top: 16px;
position: relative;
display: flex;
text-align: left;
align-items: center;
padding: ${({ theme }) => theme.spaceMap.lg}px;
border-radius: ${({ theme }) => theme.borderRadiusesMap.lg}px;
height: 174px;
gap: 20px;
overflow: hidden;
background-color: #07080c;
background: linear-gradient(90deg, #3487e5 0%, #006ae3 46.27%);
background: radial-gradient(120% 180% at 100% 100%, #62c4fb 0%, #112dbf 100%);
box-sizing: border-box;

${({ theme }) => theme.mediaQueries.md} {
gap: 2px;
gap: 6px;
padding: ${({ theme }) => theme.spaceMap.md}px;
}

@media (max-width: 396px) {
${({ theme }) => theme.mediaQueries.sm} {
cursor: pointer;
padding: ${({ theme }) => theme.spaceMap.sm}px;
}
Expand All @@ -45,11 +44,11 @@ export const ContentWrap = styled.div`
`;

export const TextHeader = styled.div`
margin-bottom: 4px;
font-size: 14px;
line-height: 24px;
font-weight: 700;
color: #fff;
margin-bottom: 4px;
`;

export const TextWrap = styled.div`
Expand All @@ -69,7 +68,7 @@ export const ButtonWrap = styled.div`
export const ButtonLinkWrap = styled.a`
display: block;

@media (max-width: 396px) {
${({ theme }) => theme.mediaQueries.sm} {
position: absolute;
top: 0;
bottom: 0;
Expand All @@ -79,10 +78,12 @@ export const ButtonLinkWrap = styled.a`
`;

export const ButtonStyle = styled(Button)`
@media (max-width: 396px) {
display: none;
}
background-color: #fff;
padding: 7px 16px;
font-size: 12px;
line-height: 20px;

@media (max-width: 396px) {
display: none;
}
`;
Loading
Loading