Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
061db6f
chore(deps): bump svgo from 3.2.0 to 3.3.3
dependabot[bot] Mar 5, 2026
b85efb0
chore(deps): bump flatted from 3.2.9 to 3.4.1
dependabot[bot] Mar 14, 2026
584bcd9
Merge pull request #273 from lidofinance/dependabot/npm_and_yarn/flat…
ev-d Mar 18, 2026
0026cee
chore(deps): bump socket.io-parser from 4.2.5 to 4.2.6
dependabot[bot] Mar 19, 2026
63e3205
refactor: update readme and delete unused wf
ev-d Mar 20, 2026
cbf0ca4
feat: add OutdatedMetrics component
ev-d Mar 20, 2026
1b32a85
Merge pull request #279 from lidofinance/feature/si-2485-update-readme
ev-d Mar 20, 2026
d3a90b0
chore(deps): bump flatted from 3.4.1 to 3.4.2
dependabot[bot] Mar 20, 2026
968e375
chore(deps): bump h3 from 1.15.5 to 1.15.9
dependabot[bot] Mar 21, 2026
6be8d2a
Merge pull request #283 from lidofinance/dependabot/npm_and_yarn/h3-1…
DiRaiks Mar 22, 2026
05575cb
Merge pull request #282 from lidofinance/dependabot/npm_and_yarn/flat…
DiRaiks Mar 22, 2026
47a0ed3
feat: update OutdatedMetrics, update 7d API response structure
ev-d Mar 23, 2026
b185402
fix: fix call getContractEvents for RoleMemberConfirmed for range of …
ev-d Mar 24, 2026
1ee9681
refactor: return comment for RoleMemberConfirmed events logs
ev-d Mar 24, 2026
2584a02
Merge pull request #278 from lidofinance/dependabot/npm_and_yarn/sock…
ev-d Mar 24, 2026
af2f589
Merge pull request #266 from lidofinance/dependabot/npm_and_yarn/svgo…
ev-d Mar 24, 2026
6d7d6ef
fix: fix overview vault addresses, fix permission settings no roles
ev-d Mar 24, 2026
592a6fa
Merge pull request #281 from lidofinance/feature/si-2469-banner-for-o…
ev-d Mar 25, 2026
276495b
Merge branch 'develop' into fix/si-2994-review-fixes
ev-d Mar 25, 2026
22e852e
Merge pull request #284 from lidofinance/fix/si-2493-get-votings-events
ev-d Mar 25, 2026
c410c3e
fix: fix duplication in RoleDescription
ev-d Mar 25, 2026
40f7c68
Merge pull request #285 from lidofinance/fix/si-2994-review-fixes
ev-d Mar 25, 2026
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
Expand Up @@ -41,7 +41,7 @@ CSP_TRUSTED_HOSTS=https://*.lido.fi
# put "true" enable report only mode for CSP
CSP_REPORT_ONLY=true
# api endpoint for reporting csp violations
CSP_REPORT_URI=https://vaults.lido.fi/api/csp-report
CSP_REPORT_URI=https://stvaults.lido.fi/api/csp-report

# allow some state overrides from browser console for QA
ENABLE_QA_HELPERS=false
Expand Down
36 changes: 0 additions & 36 deletions .github/workflows/ci-dev-testnet-2.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/ci-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
# needs: test
name: Build and deploy
steps:
- name: Sepolia testnet deploy
- name: Hoodi testnet deploy
uses: lidofinance/dispatch-workflow@v1
env:
APP_ID: ${{ secrets.APP_ID }}
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Liquid Staking Vault Widget
# stVaults Widget

### Prerequisites

- Node.js v20+
- Node.js v24+
- Yarn package manager v1

This project requires an .env file which is distributed via private communication channels. A sample can be found in .env.example
Expand Down
2 changes: 2 additions & 0 deletions features/overview/content/banners/banners.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CapitalQuarantined } from './capital-quarantined';
import { CapacityExceeded } from './capacity-exceeded';
import { ThresholdExceeded } from './threshold-exceeded';
import { DepositsRestricted } from './deposits-restricted';
import { OutdatedMetrics } from './outdated-metrics';

import { BannerContainer } from './styles';

Expand All @@ -16,6 +17,7 @@ export const Banners = () => {
<CapacityExceeded />
<ThresholdExceeded />
<DepositsRestricted />
<OutdatedMetrics />
</BannerContainer>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { OutdatedMetrics } from './outdated-metrics';
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { formatCustomDate, isNumber } from 'utils';
import { vaultTexts } from 'modules/vaults/consts';

import { NoticeContainer } from 'features/overview/shared';
import { useVaultOverview } from 'features/overview/vault-overview';

import { TextStyled } from '../styles';

const { title, description } = vaultTexts.metrics.banners.outdatedMetrics;
export const OutdatedMetrics = () => {
const { values } = useVaultOverview();
const { outdatedReportData, dateOfLastReport } = values ?? {};

if (!outdatedReportData || !isNumber(dateOfLastReport)) {
return null;
}

const date = formatCustomDate(dateOfLastReport);

return (
<NoticeContainer title={title(date)}>
<TextStyled size="xxs">{description(date)}</TextStyled>
</NoticeContainer>
);
};
2 changes: 2 additions & 0 deletions features/overview/hooks/use-vault-overview-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,8 @@ const selectOverviewData = ({
isSlashingHappened: minimalReserve > VAULTS_CONNECT_DEPOSIT,
supplyETH: overview.supply,
repayStETH: overview.repay,
outdatedReportData: vault7dApr?.outdated,
dateOfLastReport: vault7dApr?.range.toTimestamp,
isReportFresh,
};
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { FC } from 'react';
import { Tooltip, Address } from '@lidofinance/lido-ui';
import { Address } from '@lidofinance/lido-ui';

import { TooltipStyled } from './styles';

type AddressWithTooltipProps = {
address: string;
Expand All @@ -9,8 +11,8 @@ export const AddressWithTooltip: FC<AddressWithTooltipProps> = ({
address,
}) => {
return (
<Tooltip title={address}>
<TooltipStyled title={address}>
<Address symbols={9} address={address} />
</Tooltip>
</TooltipStyled>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import styled from 'styled-components';
import { Tooltip } from '@lidofinance/lido-ui';

export const TooltipStyled = styled(Tooltip)`
overflow: clip;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@ export type RoleDescriptionProps = {

const splitDescription = (description: string) => {
const words = description.split(' ').filter(Boolean);

if (words.length === 1) {
return {
descriptionText: words[0],
};
}

return {
descriptionText: words.toSpliced(0, -1).join(' '),
lastWord: words.at(-1) ?? '',
descriptionText: words.slice(0, -1).join(' '),
lastWord: words[words.length - 1] ?? '',
};
};

Expand Down
1 change: 1 addition & 0 deletions modules/vaults/api/fetch-7d-apr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type Apr7dSeries = {
};

export type Vault7DApr = {
outdated: boolean;
days: number;
count: number;
range: TimestampRange;
Expand Down
12 changes: 12 additions & 0 deletions modules/vaults/consts/texts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,18 @@ export const vaultTexts = {
},
},
},
banners: {
outdatedMetrics: {
title: (date: string) =>
`Validator Balance Spike Detected — Metrics as of ${date}`,
description: (date: string) =>
`A balance spike was detected on one or more validators, likely caused
by a side deposit or consolidation event. Due to current UI
limitations, today's metrics — Rewards, APR, Carry Spread, and
others — cannot be calculated accurately for this day. Data shown
reflects the last valid snapshot: ${date}.`,
},
},
},
// configuration for vault roles
roles: {
Expand Down
35 changes: 28 additions & 7 deletions utils/get-confirmations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,38 @@ export const getConfirmationsInfo = async <
contract.read.getConfirmExpiry(),
publicClient.getBlockNumber(),
]);

const confirmExpireInBlocks = confirmExpiry / AVG_BLOCK_TIME_SEC;
const fromBlock = currentBlock - confirmExpireInBlocks;

const safeBlockSize = 10_000n; // safe for rpc calls
const ranges: Array<Record<'fromBlock' | 'toBlock', bigint>> = [];

for (let start = fromBlock; start <= currentBlock; start += safeBlockSize) {
ranges.push({
fromBlock: start,
toBlock:
start + safeBlockSize - 1n <= currentBlock
? start + safeBlockSize - 1n
: currentBlock,
});
}

// get all logs without filtering by role, because Operator Grid uses addresses instead of roles
const logs = await publicClient.getContractEvents({
address: contract.address,
abi: contract.abi,
eventName: 'RoleMemberConfirmed',
fromBlock,
strict: true,
});
const logs = (
await Promise.all(
ranges.map(({ fromBlock, toBlock }) =>
publicClient.getContractEvents({
address: contract.address,
abi: contract.abi,
eventName: 'RoleMemberConfirmed',
strict: true,
fromBlock,
toBlock,
}),
),
)
).flat();

let confirmations = logs
// filter out confirmations that are already expired
Expand Down
36 changes: 18 additions & 18 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4051,11 +4051,6 @@
dependencies:
"@tanstack/query-core" "5.81.5"

"@trysound/sax@0.2.0":
version "0.2.0"
resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz"
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==

"@tsconfig/node10@^1.0.7":
version "1.0.9"
resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz"
Expand Down Expand Up @@ -7192,9 +7187,9 @@ flat-cache@^3.0.4:
rimraf "^3.0.2"

flatted@^3.2.9:
version "3.2.9"
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz"
integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==
version "3.4.2"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.2.tgz#f5c23c107f0f37de8dbdf24f13722b3b98d52726"
integrity sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==

fn.name@1.x.x:
version "1.1.0"
Expand Down Expand Up @@ -7524,9 +7519,9 @@ gzip-size@^6.0.0:
duplexer "^0.1.2"

h3@^1.15.5:
version "1.15.5"
resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.5.tgz#e2f28d4a66a249973bb050eaddb06b9ab55506f8"
integrity sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==
version "1.15.9"
resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.9.tgz#ee3a480674b2e35106155544cc0a6de69a6dc14f"
integrity sha512-H7UPnyIupUOYUQu7f2x7ABVeMyF/IbJjqn20WSXpMdnQB260luADUkSgJU7QTWLutq8h3tUayMQ1DdbSYX5LkA==
dependencies:
cookie-es "^1.2.2"
crossws "^0.3.5"
Expand Down Expand Up @@ -10704,6 +10699,11 @@ safe-stable-stringify@^2.3.1:
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==

sax@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.5.0.tgz#b5549b671069b7aa392df55ec7574cf411179eb8"
integrity sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==

scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz"
Expand Down Expand Up @@ -10897,9 +10897,9 @@ socket.io-client@^4.5.1:
socket.io-parser "~4.2.4"

socket.io-parser@~4.2.4:
version "4.2.5"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.5.tgz#3f41b8d369129a93268f2abecba94b5292850099"
integrity sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==
version "4.2.6"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.6.tgz#19156bf179af3931abd05260cfb1491822578a6f"
integrity sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.4.1"
Expand Down Expand Up @@ -11286,17 +11286,17 @@ svg-parser@^2.0.4:
integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==

svgo@^3.0.2:
version "3.2.0"
resolved "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz"
integrity sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==
version "3.3.3"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.3.tgz#8246aee0b08791fde3b0ed22b5661b471fadf58e"
integrity sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==
dependencies:
"@trysound/sax" "0.2.0"
commander "^7.2.0"
css-select "^5.1.0"
css-tree "^2.3.1"
css-what "^6.1.0"
csso "^5.0.5"
picocolors "^1.0.0"
sax "^1.5.0"

tailwindcss@^3.3.1:
version "3.4.10"
Expand Down
Loading