Taostats App Architecture

Always visible (header)

  • price (+/- % change), mcap, volume
  • universal search for address, hash, extrinc, block hash etc.
  • delegate app launched (will be replaced with full wallet launcher)
  • buy tao (multiple sub links)
  • corcel
  • timezone (set EVERYTHING to UTC and then let user set local timezone if they chose)

core landing

  • stats: price, mc, 24h vol, circ. supply, tot. supply, vali apr, stake apr, finalised blocks, signed extrinsics, total accounts, transfers
  • charts: historical price/vol (+trading view), historical total/active accounts, historical staked/free issuance

Following sections are core, but i feel need to be sumarised in easy to digest block on the homepage, with links through to full page section. Will give fill details for each below.

==================

Subnets & Emissions

Summary: top 5 subnets with name and emissions, tao recycled in 24h

Emissions

  • chart: emissions breakdown by subnet (historical + indicator of subnet dereg/reg)
  • emissions assignment by validator (current! this might change in modification of emissions assignment by foundation. we build for now, plan for future). This is actually a complex set of data to show neatly, we can discuss options, current implementatino is on the front page of taostats.

Subnets

Single Subnet

  • subnet specs: name, reg date, reg history, emissions %, emissions (t/24), emissions (total t)
  • subnet info: github link, dev, discord, additional links, description, hardware reqs (miner/validator)
  • metagraph
  • reg data: reg price chart (7 days), reg cost, blocks until next reg, regs per interval, last regs table
  • dereg data: last dereg incentive, historical dereg incentive/emissions
  • distributions: miner incentive distribution chart (include uid for each data point), coldkey distribution, ip distribution.
  • recycle data: recycled tao/24, total recycled tao, historical graph.
  • historical vtrust: all valid, + network mean
  • historical incenitve: high, low, mean (keys not in immunity only)

==================

Validators

Validators Main

  • performance over last 7 days (nom/24h/Kt) or all validators (top 10 by default, interactive toggles)
  • full vali list of those in sn0 with >=1024 stake: name, stake (24h change), nominators (24h change), nom/24h/Kt, val/24h, network %, logo, hotkey, short desc.
  • sync names with delegates.json --> https://github.com/opentensor/bittensor-delegates --> https://github.com/opentensor/bittensor-delegates/blob/main/public/delegates.json

Single Validator

Combination of:

  • https://x.taostats.io/validator/5Hddm3iBFD2GLT5ik7LZnT3XJUnRnN8PoeCFgGQgawUVKNm8
  • https://taostats.io/validators/taostats/ So
  • all the blockchain elements from x
  • from taostats we need a by subnet view for an overview which is visible in a single page for: updated, vtrust, and then expandable for performance metrics of historical: updated, emissions, vtrust

==================

Accounts

Accounts Main

  • table list: address, rank, free, delegated, total (don't think we need last updated as they should all be up to date).
  • filters: pagination (10,25,50,100), Balance (100,500,1k,5k,10k,50k,100k,)

Accounts Single

==================

Transfers

Most recent transfers, and link to full transfers list. Number of transfers in last 24h/7d/30d/

Transfers Main

Transfers Single

==================

Extrinsics

(does this need to be on front page, i think not) Most recent extrinsics Number of extrinsics in last 24h/7d/30d

Extrinsics Main

Extrinsics Single

==================

Blocks

Blocks Main

Blocks Single

==================

Delegation

The purpose of the delegation summary is to see the general movement of tao in and out of nominees, allowing a user to easily see if there is more of a flow towards delegating or undelgating in the previous 24h/7d/30d which allows a guage of the sentiment of holders of tao.

Delegation Main

Delegation actions are listed with filters that allow easy separation of large single movements of tao 100,500,1k,10k,50k. You can also filter by nominee/validator and/or search by a given address to isolate all delegation for that account.

Delegation Single

A single delegation even is similar to a transaction and I am not sure we need a stand alone page for this - but it is useful to have as a direct link as a delegation proof of action from our (or 3rd party) delegation app.

==================

User Dashboard (mystats)

  • you can enter any key into this to use it in a non-identifiable way. Else user encouraged to create account and login to add accounts for long term monitoring. Gatekeep some features for logged in users to encourage singup. You can used the dahsboard as a logged in user by entering your addresses, but you DO NOT have to connect the wallets in any way, there is no interaction, you are simply entering addresses to follow in your dash.

For User

  • single multiple account balance, stake, growth from delegation in 24h/7d/30d, change from transfers in 24h/7d/30d
  • downloadable CSV for the above data + link to API for more complex interactions
  • for multiple accounts you need to sign up

For Validator

  • if the key entered above is a validator hotkey from the delegates json, then validator params are shown (this means ANYONE can monitor their chosen validator or any other validaotrs if they choose) - you can also select the validator from a dropdown of validators in delegates.json.

For Miner

  • enter coldkey to map out all assocated hotkeys across all subnets
  • detailed statistics for performance and earning under that coldkey
  • historcal registrations for ALL hotkeys (including no longer regsitered) under that coldkey, including tao recycle costs
  • current performance of keys in subnets, earning, incentive, position, alerts for bottom percentile (colour coding for health)
  • filter by subnet

==================

Tokenomics

  • emissions schedule
  • halvening schedule
  • dynamic next havlvening date countdown
  • halvening delay from last 24h/7d/30d recycle
  • current issuance
  • confirmation of no pre-mine with proof of first blocks of Kusangi

==================

Network Statistics

  • wallet size breakdown
  • holder rank/size chart
  • NVL/NPL chart
  • transaction volume

==================

Infrastructure

GCP

The K8S deployments are available in the private Github

Subscriptions

  • Sentry ( Free 15 days)
  • Cloudflare ( Free )
  • GCP ( metered )

Archives Nodes Deployment

Current public endpoints:

Nakamoto:

  • Download and extract the archive from cloudflare R2 inside /data
  • Run the k8s deployment for nakamoto link

Kusanagi

  • Deploy to kubernetes from the pre-made deployment link
  • When done downloading the archive, run the cleanup job

Finney:

  • Deploy to kubernetes from the pre-made deployment link

API Endpoints (WIP)

Overview

This document provides a list of API endpoints for a blockchain explorer. These endpoints allow users to query information about blocks, transactions, addresses, and other blockchain-related data.

API Endpoints

Blocks

  • GET /blocks - Description: Retrieve a list of recent blocks. - Parameters: - limit (optional, number of blocks to return)

  • GET /blocks/{blockHash} - Description: Retrieve details of a specific block by its hash. - Parameters: - blockHash (hash of the block)

  • GET /blocks/height/{blockHeight} - Description: Retrieve details of a block by its height. - Parameters: - blockHeight (height of the block)

Transactions

  • GET /extrinsic/{extrinsicHAsh}

    • Description: Retrieve an extrinsic associated with a specific hash. It contain all the events included and the state of them.
  • GET /extrinsics?startbloc=1234&endblock=345&limit=50

    • Description: Retrieve a list of extrinsic in the block range, if not defined it return the last 50 extrinsic. This need pagination
      • Parameters:
        • startbloc (the end block we want the transactions to be included not required)
        • endblock (the end block we want the transactions to be included not required )
        • limit (the maximum number of events we want to return, if not set we return 50)
  • GET /extrinsics/{palletName}/{extrinsicName}?startbloc=1234&endblock=345&limit=50

    • Description: Retrieve a list of extrinsic in the block range, if not defined it return the last 50 extrinsic. This need pagination
      • Parameters:
        • palletName (the pallet name we want the extrinsic from, required )
        • extrinsicName (the extrinsic name we want to retrieve, required)
        • startbloc (the end block we want the transactions to be included not required)
        • endblock (the end block we want the transactions to be included not required )
        • limit (the maximum number of events we want to return, if not set we return 50)

Addresses

  • GET /addresses

    • Description: the list of all the chain address balance paginated.
  • GET /address/{address}

    • Description: Retrieve information about a specific address, including balance and transaction history.
    • Parameters:
      • address (the blockchain address)
  • GET /address/{address}/balance

    • Description: Retrieve the balance of a specific address in realtime using the blockchain.
      • Parameters:
        • address (the blockchain address)
  • GET /address/{address}/transactions?startbloc=1234&endblock=345&limit=50

    • Description: Retrieve transactions associated with a specific address. If start and end block is not set we pass the last 50 transaction. This need pagination
      • Parameters:
        • address (the blockchain address)
        • start (the end block we want the transactions to be included not required)
        • endblock (the end block we want the transactions to be included not required )
        • limit (the maximum number of events we want to return, if not set we return 50)

Pallets Information

  • GET /{palletId}/consts?block=123

    • Description: Return a list of const item metadata for constant items of the specified palletId.
    • Parameters:
      • block (the block we want the const to be included not required if not set we return the last record know)
  • GET /{palletId}/events?block=123&limit=50

    • Description: Returns a list of event item metadata for event items of the specified palletId.
    • Parameters:
      • block (the block we want the event to be included not required if not set we return the last record know)
      • limit (the maximum number of events we want to return, if not set we return 50)
  • GET /{palletId}/events/{eventId}

    • Description: Returns an event item of the specified palletId.
    • Parameters:
      • eventId (the id of the event)
  • GET /{palletId}/events?block=123&limit=50

    • Description: Returns a list of event item metadata for event items of the specified palletId.
    • Parameters:
      • block (the block we want the event to be included not required if not set we return the last record know)
      • limit (the maximum number of events we want to return, if not set we return 50)

Subnets Information

  • GET /subnets?block=123

    • Description: Return a list of all the subnets at the latest block with basic informations ( Active Keys, Active Validators, Active Dual Miners / Validators, Active Miners, Registration Cost)
      • Parameters:
        • block (the block we want the const to be included not required if not set we return the last record know)
  • GET /{subnets}/{subnetId}/miners?block=123 - Description: Return a list of all miners active in the subnet at a defined block.

    • Parameters:
      • subnetId (the id of the subnet we want to query)
      • block (the block we want the const to be included not required if not set we return the last record know)
  • GET /{subnets}/{subnetId}/infos?block=123 - Description: Return a list of all miners active in the subnet at a defined block.

    • Parameters:

      • subnetId (the id of the subnet we want to query)
      • block (the block we want the const to be included not required if not set we return the last record know)
    • Data Returned:

      • subnet specs:
        • name
        • reg date
        • emissions %
        • emissions (t/24)
        • emissions (total t)
      • subnet info:
        • github link
        • dev
        • discord
        • additional links ( exchanges )
        • description
        • hardware reqs (miner/validator)
      • metagraph
      • reg data:
        • reg price chart (7 days)
        • reg cost
        • blocks until next reg
        • regs per block
        • last regs table
      • dereg data:
        • last dereg incentive
        • historical dereg incentive/emissions
      • distributions:
        • miner incentive distribution chart (include uid for each data point)
        • coldkey distribution
        • ip distribution.
      • recycle data: recycled tao/24, total recycled tao, historical graph.
      • historical vtrust: all valid, + network mean
      • historical incenitve: high, low, mean (keys not in immunity only)
      {
      	"subnet_specs": {
      		"name": "",
      		"reg_date": "",
      		"emissions_percentage": 0,
      		"emissions_per_day": 0,
      		"total_emissions": 0
      	},
      	"subnet_info": {
      		"github_link": "",
      		"developer": [],
      		"discord": "",
      		"additional_links": {
      			"exchanges": ""
      		},
      		"description": "",
      		"hardware_requirements": {
      			"miner": "",
      			"validator": ""
      		}
      	},
      	"metagraph": {},
      	"registration_data": {
      		"reg_price_chart_7_days": [],
      		"reg_cost": 0,
      		"blocks_until_next_reg": 0,
      		"regs_per_block": 0,
      		"last_regs_table": ""
      	},
      	"deregistration_data": {
      		"last_dereg_incentive": 0,
      		"historical_dereg_incentive_emissions": ""
      	},
      	"distributions": {
      		"miner_incentive_distribution_chart": {
      			"uid": ""
      		},
      		"coldkey_distribution": "",
      		"ip_distribution": ""
      	},
      	"recycle_data": {
      		"recycled_tao_per_day": 0,
      		"total_recycled_tao": 0,
      		"historical_graph": []
      	},
      	"historical_vtrust": {
      		"all_valid": "",
      		"network_mean": 0
      	},
      	"historical_incentive": {
      		"high": 0,
      		"low": 0,
      		"mean": 0
      	}
      }
      
      
  • GET /miners?block=123 - Description: Return a list of all miners active at a defined block.

    • Parameters:
      • block (the block we want the const to be included not required if not set we return the last record know)
  • GET /miner/{minerId}?block=123 - Description: Return a list of all miners active at a defined block.

    • Parameters:
      • minerId (the the miner id we want to return the infos from)
      • block (the block we want the const to be included not required if not set we return the last record know)

Validators Information

GET /validators?block=123 - Description: Return a list of all validators active at a defined block. - Parameters: - block (the block we want the const to be included not required if not set we return the last record know) - GET /validator?validatorId=5F4tQyWrhfGVcNhoqeiNsR6&block=123 - Description: Return a single validator active at a defined block. - Parameters: - validatorId ( the id of the validator we want the informations ) - block (the block we want the const to be included not required if not set we return the last record know)

Network Statistics

  • GET /stats - Description: Retrieve blockchain network statistics, such as total number of transactions, average block time, price, total supply, Market Cap, Circulating Supply, 24h Volume, Finalised blocks, Validating APY, Signed extrinsic, Staking APY, Total Accounts, Active accounts ( account that are active the last X days it will give a chain health), Staked Supply, Total transfers.

  • GET /totalsupply

    • Description: just give the supply for CMC as a simple number, no formatting

Node Information

  • GET /node/info - Description: Retrieve information about the blockchain node, such as software version, connection count, etc.
  • GET /search - Description: General search endpoint to find blocks, transactions, or addresses. - Parameters: query (search query, could be block hash, transaction hash, or address)

Miscellaneous

  • GET /price - Description: Retrieve current price and historical price data for the blockchain's native cryptocurrency.

Notes

  • All endpoints return data in JSON format.
  • Parameters should be passed as query parameters in the URL.

Errors

  • Standard HTTP response codes are used for errors.
  • 400 Bad Request for invalid requests.
  • 404 Not Found for non-existent resources.
  • 500 Internal Server Error for server errors.

Explorer

Frontend

Backend

It’s a custom solution based on the subsquid libraries. That solution gives us the full control over the data we want to store in the database, which means it would be possible to add new fields/tables if needed or upgrade to the new and more efficient libraries in the future (if they arrive). The repo si hosted here: https://github.com/taostat/indexer

Ongoing

Frontend:

  • Preferd tech Stack:
    • React
    • Next.js
    • Jotai ( state management )

Backend:

  • API:
    • Tech Stack: Rust see discussion
    • Axum ( using Loco for flexibility and all the auth, could be a good fit to make one API for all the planned apps / miner monitoring )
    • Open API Schema
    • Swagger Explorer for testing to be deployed on the same domain
    • Do we need to compile and create various SDK for integration ?
    • Should we create a path like /accounting or /reports inside the API so we can request reports for various thing like exporting the account data, transactions, historical of validators, ... OR we want to let user create it using the API?
    • Add a system for notifications, maybe only in the app so user are a bit "forced" to download / register ( email ? ) to it and enter the system. A system for the user to be able to create their own alerts for example if a specific validator is offline for a long time, if miner perform bellow the average, ...
  • DB:
    • Undefined yet, testing:
      • BigQuery ( GCP but need to check the costs we should try to stay away from it as cost can rise fast )
      • Mariadb
      • Postgresql
  • Caching for the API via something like Redis
  • Rate Limit

Idea to get more data:

  • A mining monitoring module that miners can install and have more in dept data directly in the app/mobile app. It will also help getting data for the explorer.

Indexers Library Testing: