Skip to content

yuri-xyz/polkadot-staking-dashboard

Repository files navigation

Features

  • APY performance: Validators, along with their performances (APY) are listed in a table for the selected era. Note that the active era will display the APY as 0.00% since it is not finalized yet.

  • Historical data: The selected era can be easily set by clicking on the Select Era button on the top navigation bar. By default, the value is set to currentEra - 1 (once the current era index is available/fetched). The input also bounds the era to the current era index, so that the user cannot select a future era. The minimum era is also considered by utilizing the Staking.historyDepth constant.

  • 🔌 Connect wallet: Using the top right button Connect Wallet you can connect your wallet to the dApp. This feature makes use of the getInjectedExtensions() functions to obtain the available wallet extensions.

  • 👁️ Connect a watch-only account: You can simulate as if you were connected to another account by providing the address of that account. In other words, read-only access.

  • 🔀 Switch chains: Easily switch between Polkadot, Kusama, Westend, and Paseo chains. After switching chains, the business logic awaits the first finalized block to determine whether the light client has synced and is ready to use. By default, Westend is selected.

  • View nominations: Once an active account is connected AND has nominated, a table will be shown below the All Validators table displaying the active nominations.

  • Start nominating: If the connected account doesn't have any active nominations it can start nominating. This can be done by selecting the validators and clicking on the Nominate button which utilizes a transaction batch including the Staking.bond and Staking.nominate extrinsics. The validator selection is also limited to 16 total validators.

  • ⬆️ Bond extra/less: You can bond extra or less to all of your nominations by making use of the Staking.bond_extra and Staking.unbond extrinsics. This feature is only available when the account is connected and has nominated.

  • ❄️ Stop nominating: If the active account is nominating, a button will appear that allows the account to stop nominating by making use of the Staking.chill extrinsic.

  • 📡 Transaction status tracking: When initiating transactions, a toast notification will be shown when the transaction either fails or succeeds, including the success or error message.

  • 🔍 Staking metrics: Some useful & fundamental metrics are shown for convenience. If an account is connected, their free & bonded (staked) balance is also shown.

  • ✍️ Advanced & specialized inputs: Specialized input components are implemented for different use cases. For example, the AddressInput component is used to input, format, and validate SS58 addresses, and also shows the account's identicon. Other specialized inputs include AmountInput and BalanceInput.

  • 📱 Mobile responsiveness: Basic mobile responsiveness is implemented, including a hamburger menu for the navigation bar. This allows mobile users to interact with the dApp.

Code & Architecture

  • Business logic: Most of the business logic is organized into React hooks, which are then used within components. Simpler logic that is not reused is contained directly within the components, usually inside a useEffect hook.
  • State management: Mainly using React's built-in useState hook and also the Zustand library is used for global state management. Zustand is a small, fast, and scalable barebones state-management solution.
  • Styling & UI: The app's design & UI is made from scratch, using TailwindCSS. Some animations are facilitated by the @headlessui/react library.
  • Testing: Simple unit tests are implemented using the Vitest testing framework. These mainly focus around testing utility functions.
  • Type safety: There is a focus on type safeness and avoiding the usage of any types whenever possible. In terms of type casting, there is only 1-2 usages of the as operator in the entire codebase, ensuring that the code stays as strongly typed as possible.
  • Transactions: I've abstracted the transaction handling logic into a custom hook called useTx. This hook handles transaction creation, signing and submission, as well as tracking the transaction status. This simplifies the transaction handling process.

Featured Code Snippets

useTx hook
useTx hook usage
useChainApi hook
useApiRx hook
useBalances hook
Example usage of hooks

Possible Future Improvements

  • Additional staking features such as rebonding and other extrinsics.
  • Integration & E2E tests utilizing chopsticks.
  • Improving accessibility (e.g. using aria attributes).
  • Light theme support.
  • When executing transactions, the dry run API can be used to determine if a transaction will succeed or fail early on, saving network fees for the user.
  • Utilize local storage to persist the last connected account and chain.
  • Use the whitelisting feature of PAPI to reduce bundle size.
  • Identities of the validators are present on the People chain. Need to fetch and display them.

Building & Running

# Install dependencies
yarn install

# Run the app
yarn dev

Project Folder Structure

├── .github
│   └── workflows
│       └── test.yml
├── .papi
├── public
├── src
│   ├── assets - Images, fonts, etc.
│   ├── components - Reusable components
│   ├── hooks - Business logic & data fetching
│   ├── modals - Modal components
│   ├── test - Tests
│   ├── utils - Utility functions
│   ├── App.tsx - Main component
│   ├── constants.ts - Global constants
│   ├── index.css
│   ├── main.tsx
│   ├── types.ts
│   └── vite-env.d.ts

About

⭕ Simple Polkadot networks staking dashboard & validator tables dApp.

Resources

License

Stars

Watchers

Forks

Languages