diff --git a/README.md b/README.md
index c411631758..9f5a50ca3d 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,9 @@ podman run --d -p 8080:80 localhost/polkadot-staking-dashboard
```
+
And access the **Staking Dashboard** at http://localhost:8080/.
+
## Presentations
diff --git a/check-markdown-links-config.json b/check-markdown-links-config.json
index cfe4600290..6b075fe601 100644
--- a/check-markdown-links-config.json
+++ b/check-markdown-links-config.json
@@ -1,10 +1,15 @@
{
"httpHeaders": [
{
- "urls": ["https://github.com/", "https://guides.github.com/", "https://help.github.com/", "https://docs.github.com/"],
+ "urls": [
+ "https://github.com/",
+ "https://guides.github.com/",
+ "https://help.github.com/",
+ "https://docs.github.com/"
+ ],
"headers": {
"Accept-Encoding": "zstd, br, gzip, deflate"
}
}
]
-}
\ No newline at end of file
+}
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 1bee448bfc..fcd384bf24 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -1,5 +1,31 @@
# Changelog
+## [1.1.4](https://github.com/paritytech/polkadot-staking-dashboard/compare/v1.1.3...v1.1.4) (2024-01-28)
+
+
+### Features
+
+* **ci:** add markdown-link-check ([#1865](https://github.com/paritytech/polkadot-staking-dashboard/issues/1865)) ([7e7134e](https://github.com/paritytech/polkadot-staking-dashboard/commit/7e7134ea2a42ec56d095e0809a4eaa05f94ad793))
+* **fix:** account for staking rate in average reward rate ([#1886](https://github.com/paritytech/polkadot-staking-dashboard/issues/1886)) ([9938620](https://github.com/paritytech/polkadot-staking-dashboard/commit/9938620ee417bd42761a6e63828e3dd3ab8e7ee2))
+* **refacor:** Pool config to bootstrap app state ([#1900](https://github.com/paritytech/polkadot-staking-dashboard/issues/1900)) ([8f51a86](https://github.com/paritytech/polkadot-staking-dashboard/commit/8f51a8672b843b7cd7172144e2157148d03325ca))
+* **refactor:** Move balance syncing to static class, `activeBalances` in UI only. ([#1858](https://github.com/paritytech/polkadot-staking-dashboard/issues/1858)) ([a372487](https://github.com/paritytech/polkadot-staking-dashboard/commit/a3724879f377c38baf0e9b04e03749e0e2f65ee0))
+* **refactor:** Move Polkawatch to inline instantiation ([#1890](https://github.com/paritytech/polkadot-staking-dashboard/issues/1890)) ([d7b88bd](https://github.com/paritytech/polkadot-staking-dashboard/commit/d7b88bd57701c16ad143a6e2b70897b5086f82f6))
+* **refactor:** Move staking metrics `payee` to active balances ([#1904](https://github.com/paritytech/polkadot-staking-dashboard/issues/1904)) ([7b692e0](https://github.com/paritytech/polkadot-staking-dashboard/commit/7b692e06006448604929ec23fe510a7c7492141b))
+* **refactor:** network metrics to static, bootstrap all state before subscribe ([#1896](https://github.com/paritytech/polkadot-staking-dashboard/issues/1896)) ([08a813c](https://github.com/paritytech/polkadot-staking-dashboard/commit/08a813c7d47d2055984f7d32c1d8b34bec9791f4))
+* **refactor:** remove unneeded bonded getters ([7108e55](https://github.com/paritytech/polkadot-staking-dashboard/commit/7108e55d3f1aeeb07cdaa7cdb5608425b0d6641a))
+* **refactor:** rm `ExtrinsicsProvider`, nonces to `TxMeta` ([4194150](https://github.com/paritytech/polkadot-staking-dashboard/commit/41941509cb0d930d53f3fc98a12736b0356c6846))
+* **refactor:** Staking metrics to bootstrap and API ([#1905](https://github.com/paritytech/polkadot-staking-dashboard/issues/1905)) ([f6c0b93](https://github.com/paritytech/polkadot-staking-dashboard/commit/f6c0b93fc5fcaf2961c91cdeae770d5503766fe8))
+* **refactor:** Subscan refactor, remove fetching from Providers ([#1878](https://github.com/paritytech/polkadot-staking-dashboard/issues/1878)) ([57e2a1b](https://github.com/paritytech/polkadot-staking-dashboard/commit/57e2a1bed952b41441635dc9eba02b79d63d3fc0))
+
+
+### Bug Fixes
+
+* balances no accounts sync ([#1889](https://github.com/paritytech/polkadot-staking-dashboard/issues/1889)) ([5316283](https://github.com/paritytech/polkadot-staking-dashboard/commit/5316283029f9a28003bb25814623f768f3294fb8))
+* Render safe guards, pool useEffect fixes ([#1906](https://github.com/paritytech/polkadot-staking-dashboard/issues/1906)) ([7c0212f](https://github.com/paritytech/polkadot-staking-dashboard/commit/7c0212f428e56b2eba9c735a6299c3661dd47b25))
+* roll back Substrate Connect ([#1899](https://github.com/paritytech/polkadot-staking-dashboard/issues/1899)) ([33b5671](https://github.com/paritytech/polkadot-staking-dashboard/commit/33b5671caf5ec09240e164e82618efb15deebe81))
+* unlock Chunk unit type ([afe9b1c](https://github.com/paritytech/polkadot-staking-dashboard/commit/afe9b1c0256eb9840a375f1d7574895a07ba0f4a))
+
+
## [1.1.3](https://github.com/paritytech/polkadot-staking-dashboard/compare/v1.1.2...v1.1.3) (2024-01-15)
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index 0808168b7c..23b60e3bea 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -57,7 +57,7 @@ Going from the top-most component, the component hierarchy is set up as follows:
- `src/index.tsx`: DOM render, of little interest.
- `src/App.tsx`: wraps `` in the theme provider context and determines the active network from local storage.
-- `src/Providers.tsx`: imports and wraps `` with all the contexts using a withProviders hook. We also wrap styled component's theme provider context here to make the theme configuration work.
+- `src/Providers.tsx`: imports and wraps `` with all the contexts using a `withProviders` hook. We also wrap styled component's theme provider context here to make the theme configuration work.
- `src/Router.tsx`: contains react router ``'s, in addition to the major app presentational components.
## Development Patterns
diff --git a/package.json b/package.json
index aa3955af13..811a4221b4 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
- "@ledgerhq/hw-transport-webhid": "^6.28.2",
+ "@ledgerhq/hw-transport-webhid": "^6.28.3",
"@polkadot-cloud/assets": "^0.3.4",
"@polkadot-cloud/core": "^1.2.4",
"@polkadot-cloud/react": "^0.3.8",
@@ -47,8 +47,9 @@
"date-fns": "^3.3.1",
"framer-motion": "^11.0.3",
"html5-qrcode": "^2.3.8",
- "i18next": "^23.7.20",
+ "i18next": "^23.8.2",
"i18next-browser-languagedetector": "^7.2.0",
+ "lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1",
"qrcode-generator": "1.4.4",
"rc-slider": "^10.5.0",
@@ -57,24 +58,25 @@
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.12",
"react-helmet": "^6.1.0",
- "react-i18next": "^14.0.1",
- "react-router-dom": "^6.21.3",
+ "react-i18next": "^14.0.5",
+ "react-router-dom": "^6.22.0",
"react-scroll": "^1.9.0",
"styled-components": "^6.1.8",
- "usehooks-ts": "2.10.0"
+ "usehooks-ts": "2.14.0"
},
"devDependencies": {
"@ledgerhq/logs": "^6.12.0",
- "@types/chroma-js": "^2.4.3",
+ "@types/chroma-js": "^2.4.4",
+ "@types/lodash.debounce": "^4",
"@types/lodash.throttle": "^4.1.9",
- "@types/react": "^18.2.48",
- "@types/react-dom": "^18.2.17",
+ "@types/react": "^18.2.55",
+ "@types/react-dom": "^18.2.19",
"@types/react-helmet": "^6.1.11",
"@types/react-scroll": "^1.8.10",
"@types/styled-components": "^5.1.34",
- "@typescript-eslint/eslint-plugin": "^6.19.1",
- "@typescript-eslint/parser": "^6.19.1",
- "@vitejs/plugin-react-swc": "^3.5.0",
+ "@typescript-eslint/eslint-plugin": "^7.0.1",
+ "@typescript-eslint/parser": "^7.0.1",
+ "@vitejs/plugin-react-swc": "^3.6.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
@@ -86,13 +88,13 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-unused-imports": "^3.0.0",
"gh-pages": "^6.1.1",
- "prettier": "^3.2.4",
+ "prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^3.2.4",
"sass": "^1.70.0",
"typescript": "^5.3.3",
- "vite": "^5.0.12",
- "vite-bundle-visualizer": "^1.0.0",
- "vite-plugin-checker": "^0.6.2",
+ "vite": "^5.1.1",
+ "vite-bundle-visualizer": "^1.0.1",
+ "vite-plugin-checker": "^0.6.3",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-svgr": "^4.2.0",
"vite-tsconfig-paths": "^4.3.1",
diff --git a/src/App.tsx b/src/App.tsx
index 67259d4158..cb42545132 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -3,30 +3,20 @@
import type { FC } from 'react';
import { I18nextProvider } from 'react-i18next';
-import { DefaultNetwork } from 'consts';
import { ThemesProvider } from 'contexts/Themes';
import { i18next } from 'locale';
import { Providers } from 'Providers';
import { NetworkProvider } from 'contexts/Network';
import { ActiveAccountsProvider } from 'contexts/ActiveAccounts';
-export const App: FC = () => {
- let network = localStorage.getItem('network');
-
- if (network === null) {
- network = DefaultNetwork;
- localStorage.setItem('network', network);
- }
-
- return (
-
-
-
-
-
-
-
-
-
- );
-};
+export const App: FC = () => (
+
+
+
+
+
+
+
+
+
+);
diff --git a/src/Page.tsx b/src/Page.tsx
new file mode 100644
index 0000000000..9a2880e224
--- /dev/null
+++ b/src/Page.tsx
@@ -0,0 +1,26 @@
+// Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors
+// SPDX-License-Identifier: GPL-3.0-only
+
+import { useNetwork } from 'contexts/Network';
+import { Helmet } from 'react-helmet';
+import type { PageItem } from 'types';
+import { Page as PageWrapper } from '@polkadot-cloud/react';
+import { useTranslation } from 'react-i18next';
+
+export const Page = ({ page }: { page: PageItem }) => {
+ const { t } = useTranslation();
+ const { network } = useNetwork();
+ const { Entry, key } = page;
+
+ return (
+
+
+ {`${t(key, { ns: 'base' })} : ${t('title', {
+ context: `${network}`,
+ ns: 'base',
+ })}`}
+
+
+
+ );
+};
diff --git a/src/Providers.tsx b/src/Providers.tsx
index 54ca44430a..638e1ab413 100644
--- a/src/Providers.tsx
+++ b/src/Providers.tsx
@@ -14,16 +14,14 @@ import { FiltersProvider } from 'contexts/Filters';
import { LedgerHardwareProvider } from 'contexts/Hardware/Ledger/LedgerHardware';
import { VaultAccountsProvider } from 'contexts/Hardware/Vault/VaultAccounts';
import { HelpProvider } from 'contexts/Help';
-import { IdentitiesProvider } from 'contexts/Identities';
import { MenuProvider } from 'contexts/Menu';
import { MigrateProvider } from 'contexts/Migrate';
import { PromptProvider } from 'contexts/Prompt';
import { PluginsProvider } from 'contexts/Plugins';
-import { ActivePoolsProvider } from 'contexts/Pools/ActivePools';
+import { ActivePoolProvider } from 'contexts/Pools/ActivePool';
import { BondedPoolsProvider } from 'contexts/Pools/BondedPools';
import { PoolMembersProvider } from 'contexts/Pools/PoolMembers';
-import { PoolMembershipsProvider } from 'contexts/Pools/PoolMemberships';
-import { PoolsConfigProvider } from 'contexts/Pools/PoolsConfig';
+import { FavoritePoolsProvider } from 'contexts/Pools/FavoritePools';
import { ProxiesProvider } from 'contexts/Proxies';
import { SetupProvider } from 'contexts/Setup';
import { StakingProvider } from 'contexts/Staking';
@@ -37,9 +35,6 @@ import { PayoutsProvider } from 'contexts/Payouts';
import { useNetwork } from 'contexts/Network';
import { APIProvider } from 'contexts/Api';
import { ThemedRouter } from 'Themes';
-import type { AnyJson } from 'types';
-import type { FC } from 'react';
-import { withProviders } from 'library/Hooks';
import { OtherAccountsProvider } from 'contexts/Connect/OtherAccounts';
import { useActiveAccounts } from 'contexts/ActiveAccounts';
import { DappName } from 'consts';
@@ -47,8 +42,10 @@ import { ImportedAccountsProvider } from 'contexts/Connect/ImportedAccounts';
import { PoolPerformanceProvider } from 'contexts/Pools/PoolPerformance';
import { registerSaEvent } from 'Utils';
import { ExternalAccountsProvider } from 'contexts/Connect/ExternalAccounts';
+import type { Provider } from 'hooks/withProviders';
+import { withProviders } from 'hooks/withProviders';
+import { CommunityProvider } from 'contexts/Community';
-// Embed providers from hook.
export const Providers = () => {
const {
network,
@@ -56,8 +53,9 @@ export const Providers = () => {
} = useNetwork();
const { activeAccount, setActiveAccount } = useActiveAccounts();
- // !! Provider order matters
- const providers: (FC | [FC, AnyJson])[] = [
+ // !! Provider order matters.
+ const providers: Provider[] = [
+ UIProvider,
[APIProvider, { network }],
VaultAccountsProvider,
LedgerHardwareProvider,
@@ -85,22 +83,19 @@ export const Providers = () => {
ProxiesProvider,
HelpProvider,
PluginsProvider,
- IdentitiesProvider,
BondedProvider,
BalancesProvider,
StakingProvider,
- PoolsConfigProvider,
+ FavoritePoolsProvider,
BondedPoolsProvider,
- PoolMembershipsProvider,
PoolMembersProvider,
- ActivePoolsProvider,
+ ActivePoolProvider,
TransferOptionsProvider,
ValidatorsProvider,
FavoriteValidatorsProvider,
FastUnstakeProvider,
PayoutsProvider,
PoolPerformanceProvider,
- UIProvider,
SetupProvider,
MenuProvider,
TooltipProvider,
@@ -109,6 +104,7 @@ export const Providers = () => {
PromptProvider,
MigrateProvider,
FiltersProvider,
+ CommunityProvider,
];
return withProviders(providers, ThemedRouter);
diff --git a/src/Router.tsx b/src/Router.tsx
index f243b48797..98b83b15b4 100644
--- a/src/Router.tsx
+++ b/src/Router.tsx
@@ -4,12 +4,10 @@
import { registerLastVisited, registerSaEvent } from 'Utils';
import { usePrompt } from 'contexts/Prompt';
import { Disclaimer } from 'library/NetworkBar/Disclaimer';
-import { Body, Main, Page, Side } from '@polkadot-cloud/react';
+import { Body, Main } from '@polkadot-cloud/react';
import { extractUrlValue } from '@polkadot-cloud/utils';
-import { AnimatePresence } from 'framer-motion';
import { useEffect, useRef } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
-import { Helmet } from 'react-helmet';
import { useTranslation } from 'react-i18next';
import {
HashRouter,
@@ -33,21 +31,19 @@ import { useNetwork } from 'contexts/Network';
import { useActiveAccounts } from 'contexts/ActiveAccounts';
import { useOtherAccounts } from 'contexts/Connect/OtherAccounts';
import { useImportedAccounts } from 'contexts/Connect/ImportedAccounts';
-import { SideMenuMaximisedWidth } from 'consts';
-import { useTheme } from 'styled-components';
import { Notifications } from 'library/Notifications';
import { NotificationsController } from 'static/NotificationsController';
+import { Page } from 'Page';
export const RouterInner = () => {
const { t } = useTranslation();
- const mode = useTheme();
const { network } = useNetwork();
const { pathname, search } = useLocation();
const { accounts } = useImportedAccounts();
const { accountsInitialised } = useOtherAccounts();
const { activeAccount, setActiveAccount } = useActiveAccounts();
- const { sideMenuOpen, sideMenuMinimised, setContainerRefs } = useUi();
const { openPromptWith } = usePrompt();
+ const { setContainerRefs } = useUi();
// register landing source from URL
useEffect(() => {
@@ -64,27 +60,21 @@ export const RouterInner = () => {
registerLastVisited(utmSource);
}, []);
+ // References to outer container.
+ const mainInterfaceRef = useRef(null);
+
// Scroll to top of the window on every page change or network change.
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname, network]);
- // Set references to UI context and make available throughout app.
+ // Set container references to UI context and make available throughout app.
useEffect(() => {
setContainerRefs({
mainInterface: mainInterfaceRef,
});
}, []);
- // Update body background to `--background-default` upon theme change.
- useEffect(() => {
- const elem = document.querySelector('.core-entry');
- if (elem) {
- document.getElementsByTagName('body')[0].style.backgroundColor =
- getComputedStyle(elem).getPropertyValue('--background-default');
- }
- }, [mode]);
-
// Open default account modal if url var present and accounts initialised.
useEffect(() => {
if (accountsInitialised) {
@@ -105,9 +95,6 @@ export const RouterInner = () => {
}
}, [accountsInitialised]);
- // References to outer containers
- const mainInterfaceRef = useRef(null);
-
return (
{/* Notification popups */}
@@ -130,50 +117,32 @@ export const RouterInner = () => {
{/* Left side menu */}
-
-
-
+
{/* Main content window */}
{/* Fixed headers */}
+ {/* Isolate route errors to `Main` container */}
-
-
- {PagesConfig.map((page, i) => {
- const { Entry, hash, key } = page;
-
- return (
-
-
- {`${t(key, { ns: 'base' })} : ${t('title', {
- context: `${network}`,
- ns: 'base',
- })}`}
-
-
-
- }
- />
- );
- })}
+
+ {/* App page routes */}
+ {PagesConfig.map((page, i) => (
}
+ key={`main_interface_page_${i}`}
+ path={page.hash}
+ element={}
/>
-
-
+ ))}
+
+ {/* Default route to overview */}
+ }
+ />
+