diff --git a/.gitignore b/.gitignore index c6794c8186..cdeec9ebac 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ docs/.obsidian .docusaurus .cache-loader .yarnclean +.yarn +.pnp.cjs +.pnp.loader.mjs # Misc .DS_Store diff --git a/README.md b/README.md index cfcb1aab0f..111bf6f3c9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

Bittensor Developer Docs

-

https://docs.bittensor.com

+

https://docs.learnbittensor.org

----------------------------------------------------------------------------- @@ -17,7 +17,7 @@ In most cases you only need to follow this basic approach. If you know what you ### Installation ``` -git clone https://github.com/opentensor/developer-docs.git +git clone https://github.com/latent-to/developer-docs.git ``` ``` diff --git a/WRITING-STYLE-GUIDE.md b/WRITING-STYLE-GUIDE.md index 7023ada811..bcb33d8213 100644 --- a/WRITING-STYLE-GUIDE.md +++ b/WRITING-STYLE-GUIDE.md @@ -1,5 +1,5 @@

- + Tao Logo

@@ -7,7 +7,7 @@ ----------------------------------------------------------------------------- -When you write a developer document for Opentensor Foundation, your audience should find your documentation readable, informative, and concise. To accomplish these goals, here below are a few helpful writing style recommendations. We encourage you to stick to the writing style described on this page. +When you write a developer document for the Bittensor documentation, your audience should find your documentation readable, informative, and concise. To accomplish these goals, here below are a few helpful writing style recommendations. We encourage you to stick to the writing style described on this page. # General principles diff --git a/docs/_subnet-pages/index.md b/docs/_subnet-pages/index.md deleted file mode 100644 index 7947f213ad..0000000000 --- a/docs/_subnet-pages/index.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -title: "Subnet Pages" -hide_table_of_contents: true ---- - -import { HiAcademicCap } from "react-icons/hi2"; -import { SiRootssage } from "react-icons/si"; - - -# Subnet Pages - -This section presents key information for each subnet. Click on a subnet card to go to its details page. - -:::tip Updating subnet details page -If your subnet details page need updates, then [submit a GitHub issue](https://github.com/opentensor/developer-docs/issues/new). -::: - - - - - - - α} - title='Subnet 1' - link='/subnet-pages/subnet-1' - body='text prompting' /> - β} - title='Subnet 2' - link='/subnet-pages/subnet-2' - body='Omron' /> - γ} - title='Subnet 3' - link='/subnet-pages/subnet-3' - body='data scraping' /> - Δ} - title='Subnet 4' - link='/subnet-pages/subnet-4' - body='Targon' /> - - - - ε} - title='Subnet 5' - link='/subnet-pages/subnet-5' - body='OpenKaito Search' /> - ζ} - title='Subnet 6' - link='/subnet-pages/subnet-6' - body='Nous Finetuning' /> - η} - title='Subnet 7' - link='/subnet-pages/subnet-7' - body='storage subnet' /> - θ} - title='Subnet 8' - link='/subnet-pages/subnet-8' - body='PTN' /> - - - - ι} - title='Subnet 9' - link='/subnet-pages/subnet-9' - body='pretraining' /> - κ} - title='Subnet 10' - link='/subnet-pages/subnet-10' - body='Map reduce' /> - λ} - title='Subnet 11' - link='/subnet-pages/subnet-11' - body='transcription' /> - μ} - title='Subnet 12' - link='/subnet-pages/subnet-12' - body='Compute Horde' /> - - - - ν} - title='Subnet 13' - link='/subnet-pages/subnet-13' - body='data universe' /> - ξ} - title='Subnet 14' - link='/subnet-pages/subnet-14' - body='llm defender' /> - ο} - title='Subnet 15' - link='/subnet-pages/subnet-15' - body='blockchain insights' /> - π} - title='Subnet 16' - link='/subnet-pages/subnet-16' - body='audio subnet' /> - - - - ρ} - title='Subnet 17' - link='/subnet-pages/subnet-17' - body='flavia inference' /> - σ} - title='Subnet 18' - link='/subnet-pages/subnet-18' - body='cortex.t' /> - τ} - title='Subnet 19' - link='/subnet-pages/subnet-19' - body='vision' /> - υ} - title='Subnet 20' - link='/subnet-pages/subnet-20' - body='bitagent' /> - - - - φ} - title='Subnet 21' - link='/subnet-pages/subnet-21' - body='filetao' /> - χ} - title='Subnet 22' - link='/subnet-pages/subnet-22' - body='smart-scrape' /> - ψ} - title='Subnet 23' - link='/subnet-pages/subnet-23' - body='NicheImage' /> - ω} - title='Subnet 24' - link='/subnet-pages/subnet-24' - body='cellular automata' /> - - - - א} - title='Subnet 25' - link='/subnet-pages/subnet-25' - body='distributed training' /> - ב} - title='Subnet 26' - link='/subnet-pages/subnet-26' - body='ImageAlchemy' /> - ג} - title='Subnet 27' - link='/subnet-pages/subnet-27' - body='compute subnet' /> - ד} - title='Subnet 28' - link='/subnet-pages/subnet-28' - body='S&P 500 Oracle' /> - - - - ה} - title='Subnet 29' - link='/subnet-pages/subnet-29' - body='Fractal' /> - ו} - title='Subnet 30' - link='/subnet-pages/subnet-30' - body='Unknown' /> - ז} - title='Subnet 31' - link='/subnet-pages/subnet-31' - body='healthcare' /> - ח} - title='Subnet 32' - link='/subnet-pages/subnet-32' - body='It's AI: LLM Detection' /> - diff --git a/docs/_subnet-pages/subnet-0.md b/docs/_subnet-pages/subnet-0.md deleted file mode 100644 index 7713934d50..0000000000 --- a/docs/_subnet-pages/subnet-0.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 0" ---- - -# Subnet 0 - -## Name - -Root network - -## Netuid -0 - -## Description - -The weights for the subnets are set by the root network validators. These root network weights determine the emissions for all the subnets. See more at [Root network](../emissions.md#root-network). - -## Subnet owner - -Opentensor Foundation - -## GitHub - -https://github.com/opentensor/bittensor - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-1.md b/docs/_subnet-pages/subnet-1.md deleted file mode 100644 index 8c8adb7600..0000000000 --- a/docs/_subnet-pages/subnet-1.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 1" ---- - -# Subnet 1 - -## Name - -Text prompting - -## Netuid -1 - -## Description - -Incentivizes subnet miners who produce the best prompt completions in response to the prompts sent by the subnet validators in that subnet. - -## Subnet owner - -Macrocosmos - -## GitHub - -https://github.com/opentensor/prompting - - diff --git a/docs/_subnet-pages/subnet-10.md b/docs/_subnet-pages/subnet-10.md deleted file mode 100644 index a07db36ede..0000000000 --- a/docs/_subnet-pages/subnet-10.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 10" ---- - -# Subnet 10 - -## Name - -Map Reduce - -## Netuid -10 - -## Description - -This subnet (Map Reduce Subnet) incentivizes miners by offering rewards for contributing network bandwidth and memory resources. - -## Subnet owner - -https://github.com/dream-well/map-reduce-subnet/ - -## GitHub - -https://github.com/dream-well/map-reduce-subnet/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-11.md b/docs/_subnet-pages/subnet-11.md deleted file mode 100644 index 4af96fe40b..0000000000 --- a/docs/_subnet-pages/subnet-11.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 11" ---- - -# Subnet 11 - -## Name - -Transcription Subnet - -## Netuid -11 - -## Description - -Miners are responsible for transcribing spoken language into accurate written text using advanced speech-to-text models, while validators ensure the quality and reliability of these transcriptions. This synergetic process not only makes audio content universally accessible and searchable but also significantly amplifies its value across diverse sectors. - -## Subnet owner - -https://github.com/Cazure8/transcription-subnet - -## GitHub - -https://github.com/Cazure8/transcription-subnet - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-12.md b/docs/_subnet-pages/subnet-12.md deleted file mode 100644 index 03a7db0d7b..0000000000 --- a/docs/_subnet-pages/subnet-12.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 12" ---- - -# Subnet 12 - -## Name - -ComputeHorde - -## Netuid -12 - -## Description - -A subnet that provides compute resources. - -## Subnet owner - -https://github.com/backend-developers-ltd/ComputeHorde - -## GitHub - -https://github.com/backend-developers-ltd/ComputeHorde - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-13.md b/docs/_subnet-pages/subnet-13.md deleted file mode 100644 index 35c7e399fd..0000000000 --- a/docs/_subnet-pages/subnet-13.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Subnet 13" ---- - -# Subnet 13 - -## Name - -Data Universe - -## Netuid -13 - -## Description - -Data Universe subnet collects and stores large amounts of data from across a wide-range of sources, for use by other Subnets. This subnet is built from the ground-up with a focus on decentralization and scalability. There is no centralized entity that controls the data; the data is stored across all Miner's on the network and is queryable via the Validators. - -At launch, Data Universe is able to support up to 50 Petabytes of data across 200 miners, while only requiring ~10GB of storage on the Validator. - -## Subnet owner - -https://github.com/RusticLuftig/data-universe/ - -## GitHub - -https://github.com/RusticLuftig/data-universe/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-14.md b/docs/_subnet-pages/subnet-14.md deleted file mode 100644 index ef037ae626..0000000000 --- a/docs/_subnet-pages/subnet-14.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 14" ---- - -# Subnet 14 - -## Name - -Bittensor LLM Defender Subnet - -## Netuid -14 - -## Description - -The LLM Defender subnet provides Large Language Model (LLM) developers a way to decentralize the computing required to detect and prevent various attacks and exploits against LLM applications. - -## Subnet owner - -https://github.com/ceterum1/llm-defender-subnet/ - -## GitHub - -https://github.com/ceterum1/llm-defender-subnet/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-15.md b/docs/_subnet-pages/subnet-15.md deleted file mode 100644 index eb9f566647..0000000000 --- a/docs/_subnet-pages/subnet-15.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 15" ---- - -# Subnet 15 - -## Name - -Bittensor Blockchain Insights Subnet - -## Netuid -15 - -## Description - -Blockchain Insights Subnet is an innovative project focusing on transforming raw blockchain data into structured graph models. This project aims to provide comprehensive insights into various blockchain activities, including simple transactions, DeFi protocol transactions, and NFT exchanges. - -## Subnet owner - -https://github.com/blockchain-insights/blockchain-data-subnet/ - -## GitHub - -https://github.com/blockchain-insights/blockchain-data-subnet/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-16.md b/docs/_subnet-pages/subnet-16.md deleted file mode 100644 index 52101bf4fa..0000000000 --- a/docs/_subnet-pages/subnet-16.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 16" ---- - -# Subnet 16 - -## Name - -Audio Generation Subnetwork - -## Netuid -16 - -## Description - -This subnetwork is a decentralized system designed for text-to-audio applications within the Bittensor network. - -## Subnet owner - -https://github.com/UncleTensor/AudioSubnet/ - -## GitHub - -https://github.com/UncleTensor/AudioSubnet/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-17.md b/docs/_subnet-pages/subnet-17.md deleted file mode 100644 index 5b05013bda..0000000000 --- a/docs/_subnet-pages/subnet-17.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 17" ---- - -# Subnet 17 - -## Name - -Flavia - Model Inference Subnet - -## Netuid -17 - -## Description - -The Flavia subnet focuses on decentralized model inference at different scales. - -## Subnet owner - -https://github.com/CortexLM/flavia/ - -## GitHub - -https://github.com/CortexLM/flavia/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-18.md b/docs/_subnet-pages/subnet-18.md deleted file mode 100644 index 28d809165c..0000000000 --- a/docs/_subnet-pages/subnet-18.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Subnet 18" ---- - -# Subnet 18 - -## Name - -Cortex.t Subnet for AI Development and Synthetic Data Generation. - -## Netuid -18 - -## Description - -Cortex.t offers a dual-purpose solution that caters to the needs of app developers and innovators in the AI space. - -This subnet is meticulously designed to deliver reliable, high-quality text and image responses through API usage, utilising the decentralised Bittensor network. This subnet serves as a cornerstone for creating a fair, transparent, and manipulation-free environment for the incentivised production of intelligence (mining) and generation and fulfilment of diverse user prompts. - -## Subnet owner - -https://github.com/corcel-api/cortex.t/ - -## GitHub - -https://github.com/corcel-api/cortex.t/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-19.md b/docs/_subnet-pages/subnet-19.md deleted file mode 100644 index 9a5048e994..0000000000 --- a/docs/_subnet-pages/subnet-19.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 19" ---- - -# Subnet 19 - -## Name - -Vision - -## Netuid -19 - -## Description - -This subnet is a world of images unlocked. Recognition, Embeddings, Object detection, Segmentation. Here, we will do it all. Starting with Meta's Segment Anything Model. - -## Subnet owner - -https://github.com/namoray/vision/ - -## GitHub - -https://github.com/namoray/vision/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-2.md b/docs/_subnet-pages/subnet-2.md deleted file mode 100644 index 4a9deb59e2..0000000000 --- a/docs/_subnet-pages/subnet-2.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: "Subnet 2" ---- - -# Subnet 2 - -## Name - -Omron (𝜏, β) - -## Netuid -2 - -## Description - -The purpose of the Omron subnet is to provide verified AI inferences in order to optimize staking and re-staking yields. - -Omron allows a variety of yield optimization models to be hosted and run against the Bittensor network while being zk-verified. - -In specific, this subnet enhances the Bittensor network by providing utility to protocols and networks outside the Bittensor ecosystem. As a result, this subnet amplifies Bittensor’s mission throughout a variety of such external protocols and networks. - -Furthermore, this subnet provides internal benefits by guiding Bittensor users towards the most profitable validators to delegate to. This, in turn, benefits delegators and thereby benefits the Bittensor network as a whole. - -## Subnet owner - -https://twitter.com/omron_ai - -## GitHub - -https://github.com/inference-labs-inc/omron-subnet - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-20.md b/docs/_subnet-pages/subnet-20.md deleted file mode 100644 index 43694dd109..0000000000 --- a/docs/_subnet-pages/subnet-20.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "Subnet 20" ---- - -# Subnet 20 - -## Name - -BitAgent - -## Netuid - -20 - -## Description - -BitAgent has 2 core thrusts: - -1. **Q&A/Tasking**, available in a few flavors: -- a) with your data in real time (BYOD) -- b) summarization of large data (BYOD) -- c) logic-based reasoning -- d) agency (tool execution, operation performance) - -2. **Integrated Orchestration** - this is task completion initiated by natural language for application. - -## Subnet owner - -https://github.com/RogueTensor/bitagent_subnet - - -## GitHub - -https://github.com/RogueTensor/bitagent_subnet - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-21.md b/docs/_subnet-pages/subnet-21.md deleted file mode 100644 index 7f171ec06d..0000000000 --- a/docs/_subnet-pages/subnet-21.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 21" ---- - -# Subnet 21 - -## Name - -FileTAO - -## Netuid -21 - -## Description - -FileTAO implements a novel, multi-layered zero-knowledge interactive proof-of-spacetime algorithm. It cleverly uses Pedersen commitments, random challenges leveraging elliptic curve cryptography, sequential seed-based chained hash verification, and merkle proofs to achieve an efficient, robust, secure, and highly available decentralized storage system on the Bittensor network. - -## Subnet owner - -https://github.com/ifrit98/storage-subnet/ - -## GitHub - -https://github.com/ifrit98/storage-subnet/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-22.md b/docs/_subnet-pages/subnet-22.md deleted file mode 100644 index 5c92286bfd..0000000000 --- a/docs/_subnet-pages/subnet-22.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 22" ---- - -# Subnet 22 - -## Name - -Smart-Scrape - -## Netuid -22 - -## Description - -Smart-Scrape subnet is a cutting-edge tool hosted, designed for effective and simplified analysis of Twitter data. This subnet is ideal for researchers, marketers, and data analysts who seek to extract insightful information from Twitter with ease. - -## Subnet owner - -https://github.com/surcyf123/smart-scrape/ - -## GitHub - -https://github.com/surcyf123/smart-scrape/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-23.md b/docs/_subnet-pages/subnet-23.md deleted file mode 100644 index e11fddd3de..0000000000 --- a/docs/_subnet-pages/subnet-23.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "Subnet 23" ---- - -# Subnet 23 - -## Name - -NicheImage - -## Netuid - -23 - -## Description - -Image Generating Subnet - -## Subnet owner - -https://github.com/NicheTensor/NicheImage/ - -## GitHub - -https://github.com/NicheTensor/NicheImage/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-24.md b/docs/_subnet-pages/subnet-24.md deleted file mode 100644 index 75f8494750..0000000000 --- a/docs/_subnet-pages/subnet-24.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "Subnet 24" ---- - -# Subnet 24 - -## Name - -Cellular Automata - -## Netuid -24 - -## Description - -The primary focus of this subnet is to run, analyze, and store cellular automata to serve as a research and science accelerator. The subnet will serve as a conduit between cellular automata researchers in the scientific community and the computational resources available through the Bittensor community of miners and validators. - - -## Subnet owner - -https://github.com/vn-automata/bt-automata - -## GitHub - -https://github.com/vn-automata/bt-automata - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-25.md b/docs/_subnet-pages/subnet-25.md deleted file mode 100644 index eb32b5c566..0000000000 --- a/docs/_subnet-pages/subnet-25.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: "Subnet 25" ---- - -# Subnet 25 - -## Name - -Distributed Training Subnet - -## Netuid -25 - -## Description - -Distributed Training. - -## Subnet owner -https://github.com/bit-current/DistributedTraining - -## GitHub -https://github.com/bit-current/DistributedTraining - - diff --git a/docs/_subnet-pages/subnet-26.md b/docs/_subnet-pages/subnet-26.md deleted file mode 100644 index 9544317121..0000000000 --- a/docs/_subnet-pages/subnet-26.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 26" ---- - -# Subnet 26 - -## Name - -Image Alchemy - -## Netuid -26 - -## Description - -Image Alchemy - -## Subnet owner - -https://github.com/Supreme-Emperor-Wang/ImageAlchemy/ - -## GitHub - -https://github.com/Supreme-Emperor-Wang/ImageAlchemy/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-27.md b/docs/_subnet-pages/subnet-27.md deleted file mode 100644 index 3255f93e33..0000000000 --- a/docs/_subnet-pages/subnet-27.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Subnet 27" ---- - -# Subnet 27 - -## Name - -Compute Subnet - -## Netuid -27 - -## Description - -This is a compute-composable subnet, integrating various cloud platforms (e.g., Runpod, Lambda, AWS) into a cohesive unit. Its purpose is to enable higher-level cloud platforms to offer seamless compute composability across different underlying platforms. - -With the proliferation of cloud platforms, there's a growing need for a subnet that can seamlessly integrate these platforms, allowing efficient resource sharing and allocation. This compute-composable subnet empowers nodes to contribute computational power, with validators ensuring the integrity and efficiency of the shared resources. - -## Subnet owner - -https://github.com/neuralinternet/compute-subnet/ - -## GitHub - -https://github.com/neuralinternet/compute-subnet/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-28.md b/docs/_subnet-pages/subnet-28.md deleted file mode 100644 index e097541916..0000000000 --- a/docs/_subnet-pages/subnet-28.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "Subnet 28" ---- - -# Subnet 28 - -## Name - -Foundry S&P 500 Oracle - -## Netuid -28 - -## Description - -The Foundry S&P 500 Oracle incentivizes miners to frequently predict the S&P 500 price index during trading hours (9:30 AM - 4 PM Eastern Standard Time). This subnet serves as a suitable starting point for the traditional financial markets predictions given the S&P 500 index’s utility, accessibility, and world-wide acceptance. - -In this subnet, subnet validators send subnet miners a timestamp of a future time, for which the miners must make an S&P 500 price prediction. The miners must immediately respond with their price prediction for that given timestamp. Validators store these predictions and calculate the scores of the miners once the predictions mature. Miners then receive ranks to stack up against one another, naturally incentivizing competition. - -## Subnet owner -https://foundrydigital.com/accelerate/ - -## GitHub - -https://github.com/teast21/snpOracle - - diff --git a/docs/_subnet-pages/subnet-29.md b/docs/_subnet-pages/subnet-29.md deleted file mode 100644 index ea7dbe6d10..0000000000 --- a/docs/_subnet-pages/subnet-29.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 29" ---- - -# Subnet 29 - -## Name - -Fractal: Text-to-Video Generation Grid for Edge-Node Inference - -## Netuid -29 - -## Description - -Fractal, taking inspiration from Manifold Labs' Deterministic Verification Network, is utilizing deterministic verification to create a grid of decentralized nodes to perform inference for video generation. By incentivizing users to host text-to-video models, this subnet allows Fractal to develop a mechanism that optimizes how end-user inference requests are handled to minimize latency. Additionally, the subnet is incredibly gamification-resistant, as a random seed is generated for each inference request, and if the Verifier and Prover seeds do not match, the Prover will be penalized. - -## Subnet owner - -https://github.com/fractal-net/fractal - -## GitHub - -https://github.com/fractal-net/fractal - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-3.md b/docs/_subnet-pages/subnet-3.md deleted file mode 100644 index 333247b738..0000000000 --- a/docs/_subnet-pages/subnet-3.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: "Subnet 3" ---- - -# Subnet 3 - -## Name - -Scraping Subnet - -## Netuid -3 - -## Description - -Data scraping is a critical component in numerous AI and machine learning models, often acting as the foundational layer for various subnets, including [Subnet 1](./subnet-1.md). - -The objective of this subnet is to harvest data from platforms such as Reddit, Twitter, and other social media sites, and aggregate this information into shared storage solutions like Wasabi s3 storage. - -Looking ahead, the developers of this subnet intend to leverage the storage subnet of Bittensor to augment the data storage capabilities. - -## Subnet owner - -https://github.com/gitphantomman/scraping_subnet/ - -## GitHub - -https://github.com/gitphantomman/scraping_subnet/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-30.md b/docs/_subnet-pages/subnet-30.md deleted file mode 100644 index 16addc2186..0000000000 --- a/docs/_subnet-pages/subnet-30.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 30" ---- - -# Subnet 30 - -## Name - -TBD - -## Netuid -30 - -## Description - -TBD - -## Subnet owner - -TBD - -## GitHub - -TBD - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-31.md b/docs/_subnet-pages/subnet-31.md deleted file mode 100644 index 9f5e56653b..0000000000 --- a/docs/_subnet-pages/subnet-31.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Subnet 31" ---- - -# Subnet 31 - -## Name - -Healthcare subnet - -## Netuid -31 - -## Description - -In this innovative healthcare subnet, miners play a crucial role in contributing to disease diagnosis by predicting from medical images. Through continuous training, miners strive to improve their models, with more accurate models earning substantial rewards. Miners have the flexibility to adapt and enhance the structure of their models, datasets, and other factors influencing model accuracy. This collaborative effort aims to advance disease prediction and underscores the vital role miners play in shaping the future of medical diagnostics. - -Validators play a pivotal role in evaluating miner's models by periodically sending diverse images for assessment. They meticulously score miners based on their responses, contributing to the ongoing refinement of models and ensuring the highest standards of performance and accuracy in our collaborative network. - - -## Subnet owner - -https://github.com/bthealthcare/healthcare-subnet - -## GitHub - -https://github.com/bthealthcare/healthcare-subnet - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-32.md b/docs/_subnet-pages/subnet-32.md deleted file mode 100644 index da6bed0b18..0000000000 --- a/docs/_subnet-pages/subnet-32.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: "Subnet 32" ---- - -# Subnet 32 - -## Name - -It's AI: LLM Detection solution - -## Netuid -32 - -## Description - -This subnet focuses on the detection of AI-generated content. Given the rapid growth of LLM-generated text, such as -ChatGPT's output of 100 billion words daily compared to humans' 100 trillion, -we believe that the ability to accurately determine AI-generated text will become increasingly necessary. - -For example, here are some scenarios where LLM detection is important: - -* **For ML-engineers**. Whether you are sourcing training data, developing a foundational LLM, or fine-tuning on your own data, -you need to ensure that generative text does not make it into your training set. We can help. -* **For teachers**. While tools like ChatGPT offer numerous benefits for the educational sector, these tools also present opportunities for students to cheat on assignments and exams. -Therefore, it is crucial to differentiate between responses authored by genuine students and those generated by LLMs. -* **For bloggers**. Many bloggers are now faced with a lot of AI-generated comments in -their social networks. These comments are not really meaningful, yet they attract the attention of their audience and promote unrelated products. -With our subnet, you can easily identify which comments are ai-generated and automatically ban them. - -And many more, like: -* **For writers**. By utilizing an LLM detection system, writers can assess their text, segment by segment, to identify sections that appear -machine-generated. This enables the writers to refine these areas to enhance the overall human-like quality of their writing. -* **For recruiting**. Have you noticed these days you are receiving far more applications with lower candidate quality? -AI has enabled people to spam the hiring teams with artificially written cover -letters and assessments. We help you find the candidates who care about your mission and your quality standards. -* **For cybersecurity**. Scammers can leverage LLMs to quickly and easily create realistic and personalized phishing emails. -We can help you determine the provenance of any document or email you are reviewing. - -As you can see there are a lot of areas where AI detection can -be very helpful. We believe that this LLM-detection subnet -not only is a useful tool at a good price for people to use, -but it also encourages competition to make better and smarter ways to spot AI-generated content. - -## Subnet owner - -[https://github.com/It-s-AI/llm-detection](https://github.com/It-s-AI/llm-detection.git) - -## GitHub - -[https://github.com/It-s-AI/llm-detection](https://github.com/It-s-AI/llm-detection.git) - - diff --git a/docs/_subnet-pages/subnet-4.md b/docs/_subnet-pages/subnet-4.md deleted file mode 100644 index bf594d0a6f..0000000000 --- a/docs/_subnet-pages/subnet-4.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Subnet 4" ---- - -# Subnet 4 - -## Name - -**TARGON**: A Redundant Deterministic Verification of Large Language Models. - -## Netuid -4 - -## Description - -TARGON is a redundant deterministic verification mechanism that can be used to interpret and analyze ground truth sources and a query. - -## Subnet owner - -https://github.com/manifold-inc/targon/ - -## GitHub - -https://github.com/manifold-inc/targon/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-5.md b/docs/_subnet-pages/subnet-5.md deleted file mode 100644 index 37c9df1a6b..0000000000 --- a/docs/_subnet-pages/subnet-5.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: "Subnet 5" ---- - -# Subnet 5 - -## Name - -OpenKaito - -## Netuid -5 - -## Description - -A search index plays a crucial role in accessing information within Web3 and serves as the foundation for RAG applications. OpenKaito is dedicated to constructing a decentralized search index for Web3, and its incentive mechanism can be outlined as follows: - -1. Miners are encouraged to develop high-quality and efficient indexing and ranking schemes for Web3 data. - -2. Validators will submit structured or vector retrieval queries to perform spot checks on the indexing quality of the miners, using LLM. For instance, for a query "optimism", validators should anticipate receiving high quality content from miners. Miners are incentivized to differentiate between the English word "optimism" and the crypto project "optimism" within massive amounts of X (Twitter) data. The final reward will be determined based on the quality, ranking, recency, and uniqueness of the data indexed by miners. - -3. By collectively executing large-scale content understanding, indexing, and ranking, a decentralized search engine and data analytics platform can be established on top of OpenKaito. - -## Subnet owner - -https://www.kaito.ai - -## GitHub - -https://github.com/OpenKaito/openkaito - - diff --git a/docs/_subnet-pages/subnet-6.md b/docs/_subnet-pages/subnet-6.md deleted file mode 100644 index 5c97e45cb7..0000000000 --- a/docs/_subnet-pages/subnet-6.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Subnet 6" ---- - -# Subnet 6 - -## Name - -Nous Finetuning Subnet - -## Netuid -6 - -## Description - -The Nous-Bittensor subnet rewards miners for fine-tuning Large Language Models (LLMs) with data generated from a continuous stream of synthetic data provided by subnet 18 (also on Bittensor). It is the first-ever continuous fine-tuning benchmark, with new data generated daily, and the first incentivized fine-tuning benchmark. - -Additionally, it is the first Bittensor subnet to perform true cross-boundary communication, where data from one subnet is utilized in a secondary subnet. - -## Subnet owner - -[Nous Research](https://nousresearch.com/) - -## GitHub - -https://github.com/NousResearch/finetuning-subnet - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-7.md b/docs/_subnet-pages/subnet-7.md deleted file mode 100644 index d6d0562147..0000000000 --- a/docs/_subnet-pages/subnet-7.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "Subnet 7" ---- - -# Subnet 7 - -## Name - -Storage subnet. - -## Netuid - -7 - -## Description - -The storage subnet will allow nodes to contribute storage space, employing a prototype incentive mechanism similar to Filecoin. It will offer decentralized storage solutions, allowing nodes to serve their hard drive space to the network, proven to validators utilizing Yuma consensus. - -## Subnet owner - -https://github.com/tensorage/tensorage/ - -## GitHub - -https://github.com/tensorage/tensorage/ - - \ No newline at end of file diff --git a/docs/_subnet-pages/subnet-8.md b/docs/_subnet-pages/subnet-8.md deleted file mode 100644 index fad6e64ce0..0000000000 --- a/docs/_subnet-pages/subnet-8.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Subnet 8" ---- - -# Subnet 8 - -## Name - -Proprietary Trading Network (PTN) - -## Netuid - -8 - -## Description - -The PTN subnet receives signals from quant and machine learning trading systems, and delivers world's most complete trading signals across a variety of asset classes. - -PTN is the most challenging & competitive subnet in the world. Our subnet miners must provide futures-based signals (long and short) that are highly efficient and effective across various markets (forex, crypto, indices). The top subnet miners provide most returns while never exceeding the drawdown limits. - -## Subnet owner - -[https://www.taoshi.io/](https://www.taoshi.io/) - -## GitHub - -https://github.com/taoshidev/proprietary-trading-network - - diff --git a/docs/_subnet-pages/subnet-9.md b/docs/_subnet-pages/subnet-9.md deleted file mode 100644 index 467f515eb7..0000000000 --- a/docs/_subnet-pages/subnet-9.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: "Subnet 9" ---- - -# Subnet 9 - -## Name - -Pretrain Subnet - -## Netuid -9 - -## Description - -This subnet rewards miners for producing pretrained Foundation-Models on the Falcon Refined Web dataset. It acts like a continuous benchmark whereby miners are rewarded for attaining the best losses on randomly sampled pages of Falcon given a consistent model architecture. The reward mechanism works as follows: - -1. Miners train and periodically host trained model weights linked to their miner key as exampled by the code in neurons/miner.py. -2. Validators run a continuous eval on the hosted models, performing the validation system outlined in neurons/validator.py and setting weights to the chain based on the performance of each miner on the Falcon dataset. -3. The chain aggregates weights from all active validators and runs Yuma Consensus to determine the proportion of TAO emission rewarded to miners and validators. - -## Subnet owner - -Macrocosmos & collaborators - -## GitHub - -https://github.com/RaoFoundation/pretraining - - diff --git a/docs/bittensor-networks.md b/docs/bittensor-networks.md deleted file mode 100644 index fefbd67db6..0000000000 --- a/docs/bittensor-networks.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "Bittensor Networks" ---- - -# Bittensor Networks - -The below table presents Bittensor networks and a few details: - -| DESCRIPTION | MAINNET | TESTNET | DEVNET | -|:---------------------|:------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------| -| **Chain URL** | wss://entrypoint-finney.opentensor.ai:443 | wss://test.finney.opentensor.ai:443 | wss://dev.chain.opentensor.ai:443 | -| **Example Usage** | Default | `btcli wallet swap_hotkey --subtensor.chain_endpoint wss://dev.chain.opentensor.ai:443` **or** `btcli wallet swap_hotkey --subtensor.network test` | `btcli wallet swap_hotkey --subtensor.chain_endpoint wss://dev.chain.opentensor.ai:443` | -| **Block processing** | One block every 12 seconds | One block every 12 seconds | One block every 12 seconds | -| **Mainnet Archive** | wss://archive.chain.opentensor.ai:443 | None | None | -| **Mainnet Lite** | wss://lite.chain.opentensor.ai:443 | None | None | -| **Experimental Mainnet Lite** | wss://lite.finney.test.opentensor.ai:443 | None | None | -| **Network Purpose** | For all | For all | **For OTF-internal development only** | -| **Faucet** | None | None | Available on internal project-basis | -| **Test TAO** | None | Available on request (not compatible with devnet test TAO) | Available internally on request (not compatible with testnet test TAO) | - diff --git a/docs/btcli.md b/docs/btcli.md deleted file mode 100644 index 771bd50b8c..0000000000 --- a/docs/btcli.md +++ /dev/null @@ -1,6882 +0,0 @@ ---- -title: "Bittensor CLI: btcli Reference Document" ---- - -# Bittensor CLI: `btcli` Reference Document - -Command line interface (CLI) for Bittensor. Uses the values in the configuration file. These values can be overriden by passing them explicitly in the command line. - -See [Getting Started](./getting-started/install-btcli.md) to install `btcli`. - -Command line interface (CLI) for Bittensor. Uses the values in the configuration file. These values can be - overriden by passing them explicitly in the command line. - -**Usage**: - -```console -btcli [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--version`: Show BTCLI version -* `--commands`: Show BTCLI commands -* `--install-completion`: Install completion for the current shell. -* `--show-completion`: Show completion for the current shell, to copy it or customize the installation. -* `--help`: Show this message and exit. - -**Commands**: - -* `config`: Config commands, aliases: `c`, `conf` -* `conf` -* `c` -* `wallet`: Wallet commands, aliases: `wallets`, `w` -* `w` -* `wallets` -* `stake`: Stake commands, alias: `st` -* `st` -* `sudo`: Sudo commands, alias: `su` -* `su` -* `subnets`: Subnets commands, alias: `s`, `subnet` -* `s` -* `subnet` -* `weights`: Weights commands, aliases: `wt`, `weight` -* `wt` -* `weight` -* `utils` - -## `btcli config` - -**Usage**: - -```console -btcli config [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `set`: Sets or updates configuration values in... -* `get`: Prints the current config file in a table. -* `clear`: Clears the fields in the config file and... -* `metagraph`: Command option to configure the display of... - -### `btcli config set` - -Sets or updates configuration values in the BTCLI config file. - -This command allows you to set default values that will be used across all BTCLI commands. - -**Usage:** - -Interactive mode: - ``` - btcli config set - ``` - -Set specific values: - ``` - btcli config set --wallet-name default --network finney - ``` - ``` - btcli config set --safe-staking --rate-tolerance 0.1 - ``` - -Note: -- Network values can be network names (e.g., 'finney', 'test') or websocket URLs -- Rate tolerance is specified as a decimal (e.g., 0.05 for 0.05%) -- Changes are saved to ~/.bittensor/btcli.yaml -- Use `btcli config get` to view current settings - -**Usage**: - -```console -btcli config set [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--cache, --cache / --no-cache, --no_cache`: Disable caching of some commands. This will disable the `--reuse-last` and `--html` flags on commands such as `subnets metagraph`, `stake show` and `subnets list`. -* `--slippage, --slippage-tolerance, --tolerance FLOAT`: Set the rate tolerance percentage for transactions (e.g. 0.1 for 0.1%). -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: Enable or disable safe staking mode. -* `--allow-partial-stake, --partial, --allow / --no-allow-partial-stake, --no-partial, --not-allow` -* `--help`: Show this message and exit. - -### `btcli config get` - -Prints the current config file in a table. - -**Usage**: - -```console -btcli config get [OPTIONS] -``` - -**Options**: - -* `--help`: Show this message and exit. - -### `btcli config clear` - -Clears the fields in the config file and sets them to 'None'. - - - - To clear the 'chain' and 'network' fields: - - ``` - btcli config clear --chain --network - ``` - - - To clear your config entirely: - - ``` - btcli config clear --all - ``` - -**Usage**: - -```console -btcli config clear [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name` -* `-p, --wallet-path, --wallet_path, --wallet.path` -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey` -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint` -* `--cache` -* `--slippage, --slippage-tolerance, --tolerance` -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: [default: no-safe-staking] -* `--allow-partial-stake, --partial, --allow / --no-allow-partial-stake, --no-partial, --not-allow`: [default: no-allow-partial-stake] -* `--all` -* `--help`: Show this message and exit. - -### `btcli config metagraph` - -Command option to configure the display of the metagraph columns. - -**Usage**: - -```console -btcli config metagraph [OPTIONS] -``` - -**Options**: - -* `--reset`: Restore the display of metagraph columns to show all columns. -* `--help`: Show this message and exit. - -## `btcli conf` - -**Usage**: - -```console -btcli conf [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `set`: Sets or updates configuration values in... -* `get`: Prints the current config file in a table. -* `clear`: Clears the fields in the config file and... -* `metagraph`: Command option to configure the display of... - -### `btcli conf set` - -Sets or updates configuration values in the BTCLI config file. - -This command allows you to set default values that will be used across all BTCLI commands. - -**Usage:** - -Interactive mode: - ``` - btcli config set - ``` - -Set specific values: - ``` - btcli config set --wallet-name default --network finney - ``` - ``` - btcli config set --safe-staking --rate-tolerance 0.1 - ``` - -Note: -- Network values can be network names (e.g., 'finney', 'test') or websocket URLs -- Rate tolerance is specified as a decimal (e.g., 0.05 for 0.05%) -- Changes are saved to ~/.bittensor/btcli.yaml -- Use `btcli config get` to view current settings - -**Usage**: - -```console -btcli conf set [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--cache, --cache / --no-cache, --no_cache`: Disable caching of some commands. This will disable the `--reuse-last` and `--html` flags on commands such as `subnets metagraph`, `stake show` and `subnets list`. -* `--slippage, --slippage-tolerance, --tolerance FLOAT`: Set the rate tolerance percentage for transactions (e.g. 0.1 for 0.1%). -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: Enable or disable safe staking mode. -* `--allow-partial-stake, --partial, --allow / --no-allow-partial-stake, --no-partial, --not-allow` -* `--help`: Show this message and exit. - -### `btcli conf get` - -Prints the current config file in a table. - -**Usage**: - -```console -btcli conf get [OPTIONS] -``` - -**Options**: - -* `--help`: Show this message and exit. - -### `btcli conf clear` - -Clears the fields in the config file and sets them to 'None'. - - - - To clear the 'chain' and 'network' fields: - - ``` - btcli config clear --chain --network - ``` - - - To clear your config entirely: - - ``` - btcli config clear --all - ``` - -**Usage**: - -```console -btcli conf clear [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name` -* `-p, --wallet-path, --wallet_path, --wallet.path` -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey` -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint` -* `--cache` -* `--slippage, --slippage-tolerance, --tolerance` -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: [default: no-safe-staking] -* `--allow-partial-stake, --partial, --allow / --no-allow-partial-stake, --no-partial, --not-allow`: [default: no-allow-partial-stake] -* `--all` -* `--help`: Show this message and exit. - -### `btcli conf metagraph` - -Command option to configure the display of the metagraph columns. - -**Usage**: - -```console -btcli conf metagraph [OPTIONS] -``` - -**Options**: - -* `--reset`: Restore the display of metagraph columns to show all columns. -* `--help`: Show this message and exit. - -## `btcli c` - -**Usage**: - -```console -btcli c [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `set`: Sets or updates configuration values in... -* `get`: Prints the current config file in a table. -* `clear`: Clears the fields in the config file and... -* `metagraph`: Command option to configure the display of... - -### `btcli c set` - -Sets or updates configuration values in the BTCLI config file. - -This command allows you to set default values that will be used across all BTCLI commands. - -**Usage:** -Interactive mode: - ``` - btcli config set - ``` - -Set specific values: - ``` - btcli config set --wallet-name default --network finney - ``` - ``` - btcli config set --safe-staking --rate-tolerance 0.1 - ``` - -Note: -- Network values can be network names (e.g., 'finney', 'test') or websocket URLs -- Rate tolerance is specified as a decimal (e.g., 0.05 for 0.05%) -- Changes are saved to ~/.bittensor/btcli.yaml -- Use `btcli config get` to view current settings - -**Usage**: - -```console -btcli c set [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--cache, --cache / --no-cache, --no_cache`: Disable caching of some commands. This will disable the `--reuse-last` and `--html` flags on commands such as `subnets metagraph`, `stake show` and `subnets list`. -* `--slippage, --slippage-tolerance, --tolerance FLOAT`: Set the rate tolerance percentage for transactions (e.g. 0.1 for 0.1%). -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: Enable or disable safe staking mode. -* `--allow-partial-stake, --partial, --allow / --no-allow-partial-stake, --no-partial, --not-allow` -* `--help`: Show this message and exit. - -### `btcli c get` - -Prints the current config file in a table. - -**Usage**: - -```console -btcli c get [OPTIONS] -``` - -**Options**: - -* `--help`: Show this message and exit. - -### `btcli c clear` - -Clears the fields in the config file and sets them to 'None'. - - - - To clear the 'chain' and 'network' fields: - - ``` - btcli config clear --chain --network - ``` - - - To clear your config entirely: - - ``` - btcli config clear --all - ``` - -**Usage**: - -```console -btcli c clear [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name` -* `-p, --wallet-path, --wallet_path, --wallet.path` -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey` -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint` -* `--cache` -* `--slippage, --slippage-tolerance, --tolerance` -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: [default: no-safe-staking] -* `--allow-partial-stake, --partial, --allow / --no-allow-partial-stake, --no-partial, --not-allow`: [default: no-allow-partial-stake] -* `--all` -* `--help`: Show this message and exit. - -### `btcli c metagraph` - -Command option to configure the display of the metagraph columns. - -**Usage**: - -```console -btcli c metagraph [OPTIONS] -``` - -**Options**: - -* `--reset`: Restore the display of metagraph columns to show all columns. -* `--help`: Show this message and exit. - -## `btcli view dashboard` - -Display html dashboard with subnets list, stake, and neuron information. - -**Usage**: - -```console -btcli view dashboard -``` - -## `btcli wallet` - -**Usage**: - -```console -btcli wallet [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `list`: Displays all the wallets and their... -* `swap-hotkey`: Swap hotkeys of a given wallet on the... -* `regen-coldkey`: Regenerate a coldkey for a wallet on the... -* `regen-coldkeypub`: Regenerates the public part of a coldkey... -* `regen-hotkey`: Regenerates a hotkey for a wallet. -* `new-hotkey`: Create a new hotkey for a wallet. -* `new-coldkey`: Create a new coldkey. -* `create`: Create a complete wallet by setting up... -* `balance`: Check the balance of the wallet. -* `history`: Show the history of the transfers carried... -* `overview`: Displays a detailed overview of the user's... -* `transfer`: Send TAO tokens from one wallet to another... -* `inspect`: Displays the details of the user's wallet... -* `faucet`: Obtain test TAO tokens by performing Proof... -* `set-identity`: Create or update the on-chain identity of... -* `get-identity`: Shows the identity details of a user's... -* `sign`: Allows users to sign a message with the... -* `swap_hotkey`: Swap hotkeys of a given wallet on the... -* `regen_coldkey`: Regenerate a coldkey for a wallet on the... -* `regen_coldkeypub`: Regenerates the public part of a coldkey... -* `regen_hotkey`: Regenerates a hotkey for a wallet. -* `new_hotkey`: Create a new hotkey for a wallet. -* `new_coldkey`: Create a new coldkey. -* `set_identity`: Create or update the on-chain identity of... -* `get_identity`: Shows the identity details of a user's... - -### `btcli wallet list` - -Displays all the wallets and their corresponding hotkeys that are located in the wallet path specified in the config. - -The output display shows each wallet and its associated `ss58` addresses for the coldkey public key and any hotkeys. The output is presented in a hierarchical tree format, with each wallet as a root node and any associated hotkeys as child nodes. The `ss58` address is displayed for each coldkey and hotkey that is not encrypted and exists on the device. - -Upon invocation, the command scans the wallet directory and prints a list of all the wallets, indicating whether the -public keys are available (`?` denotes unavailable or encrypted keys). - - -``` -btcli wallet list --path ~/.bittensor -``` - -Note: This command is read-only and does not modify the filesystem or the blockchain state. It is intended for use with the Bittensor CLI to provide a quick overview of the user's wallets. - -**Usage**: - -```console -btcli wallet list [OPTIONS] -``` - -**Options**: - -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet swap-hotkey` - -Swap hotkeys of a given wallet on the blockchain. For a registered key pair, for example, a (coldkeyA, hotkeyA) pair, this command swaps the hotkeyA with a new, unregistered, hotkeyB to move the original registration to the (coldkeyA, hotkeyB) pair. - -**Usage:** - -The command is used to swap the hotkey of a wallet for another hotkey on that same wallet. - -**Important:** - -- Make sure that your original key pair (coldkeyA, hotkeyA) is already registered. -- Make sure that you use a newly created hotkeyB in this command. A hotkeyB that is already registered cannot be used in this command. -- Finally, note that this command requires a fee of 1 TAO for recycling and this fee is taken from your wallet (coldkeyA). - -**Example:** - -``` -btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey -``` - -**Usage**: - -```console -btcli wallet swap-hotkey [OPTIONS] [DESTINATION_HOTKEY_NAME] -``` - -**Arguments**: - -* `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli wallet regen-coldkey` - -Regenerate a coldkey for a wallet on the Bittensor blockchain network. - -This command is used to create a new coldkey from an existing mnemonic, seed, or JSON file. - -**Usage:** - -Users can specify a mnemonic, a seed string, or a JSON file path to regenerate a coldkey. The command supports optional password protection for the generated key. - -**Example:** - -``` -btcli wallet regen-coldkey --mnemonic "word1 word2 ... word12" -``` - - -Note: This command is critical for users who need to regenerate their coldkey either for recovery or for security reasons. - -**Usage**: - -```console -btcli wallet regen-coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet regen-coldkeypub` - -Regenerates the public part of a coldkey (coldkeypub.txt) for a wallet. - -Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your coldkeypub.txt that you have on another machine to regenerate the coldkeypub.txt on this new machine. - -**Usage:** - -The command requires either a public key in hexadecimal format or an ``SS58`` address from the existing coldkeypub.txt from old machine to regenerate the coldkeypub on the new machine. - -**Example:** - -``` -btcli wallet regen_coldkeypub --ss58_address 5DkQ4... -``` - -Note: This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old coldkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. - -**Usage**: - -```console -btcli wallet regen-coldkeypub [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--public-key-hex TEXT`: The public key in hex format. -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet regen-hotkey` - -Regenerates a hotkey for a wallet. - -Similar to regenerating a coldkey, this command creates a new hotkey from a mnemonic, seed, or JSON file. - -**Usage:** - -Users can provide a mnemonic, seed string, or a JSON file to regenerate the hotkey. The command supports optional password protection and can overwrite an existing hotkey. - - -``` -btcli wallet regen_hotkey --seed 0x1234... -``` - -Note: This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery. -It should be used with caution to avoid accidental overwriting of existing keys. - -**Usage**: - -```console -btcli wallet regen-hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet new-hotkey` - -Create a new hotkey for a wallet. - -**Usage:** - -This command is used to generate a new hotkey for managing a neuron or participating in a subnet. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting the -existing hotkey. - -**Example:** - -``` -btcli wallet new-hotkey --n_words 24 -``` - -Note: This command is useful to create additional hotkeys for different purposes, such as running multiple subnet miners or subnet validators or separating operational roles within the Bittensor network. - -**Usage**: - -```console -btcli wallet new-hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet new-coldkey` - -Create a new coldkey. A coldkey is required for holding TAO balances and performing high-value transactions. - -**Usage:** - -The command creates a new coldkey. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting an existing coldkey. - -**Example:** - -``` -btcli wallet new_coldkey --n_words 15 -``` - -Note: This command is crucial for users who need to create a new coldkey for enhanced security or as part of setting up a new wallet. It is a foundational step in establishing a secure presence on the Bittensor network. - -**Usage**: - -```console -btcli wallet new-coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet create` - -Create a complete wallet by setting up both coldkey and hotkeys. - -**Usage:** - -The command creates a new coldkey and hotkey. It provides an option for mnemonic word count. It supports password protection for the coldkey and allows overwriting of existing keys. - -**Example:** - -``` -btcli wallet create --n_words 21 -``` - -Note: This command is for new users setting up their wallet for the first time, or for those who wish to completely renew their wallet keys. It ensures a fresh start with new keys for secure and effective participation in the Bittensor network. - -**Usage**: - -```console -btcli wallet create [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words INTEGER` -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet balance` - -Check the balance of the wallet. This command shows a detailed view of the wallet's coldkey balances, including free and staked balances. - -You can also pass multiple ss58 addresses of coldkeys to check their balance (using --ss58). - -**Example:** - -- To display the balance of a single wallet, use the command with the `--wallet-name` argument and provide the wallet name: - - ``` - btcli w balance --wallet-name WALLET - ``` - -- To use the default config values, use: - - ``` - btcli w balance - ``` - -- To display the balances of all your wallets, use the `--all` argument: - - ``` - btcli w balance --all - ``` - -- To display the balances of ss58 addresses, use the `--ss58` argument: - - ``` - btcli w balance --ss58 <ss58_address> --ss58 <ss58_address> - ``` - -**Usage**: - -```console -btcli wallet balance [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `-a, --all`: Whether to display the balances for all the wallets. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet history` - -Show the history of the transfers carried out with the provided wallet on the Bittensor network. - -**Usage:** - -The output shows the latest transfers of the provided wallet, showing the columns 'From', 'To', 'Amount', 'Extrinsic ID' and 'Block Number'. - -**Example:** - -``` -btcli wallet history -``` - -**Usage**: - -```console -btcli wallet history [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet overview` - -Displays a detailed overview of the user's registered accounts on the Bittensor network. - -This command compiles and displays comprehensive information about each neuron associated with the user's wallets, including both hotkeys and coldkeys. It is especially useful for users managing multiple accounts or looking for a summary of their network activities and stake distributions. - -**Usage:** - -``` -btcli wallet overview -``` - -``` -btcli wallet overview --all -``` - -Note: This command is read-only and does not modify the blockchain state or account configuration. -It provides a quick and comprehensive view of the user's network presence, making it useful for monitoring account status, -stake distribution, and overall contribution to the Bittensor network. - -**Usage**: - -```console -btcli wallet overview [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-a, --all`: See an overview for all the wallets -* `--sort-by, --sort_by TEXT`: Sort the hotkeys by the specified column title. For example: name, uid, axon. -* `--sort-order, --sort_order TEXT`: Sort the hotkeys in the specified order (ascending/asc or descending/desc/reverse). -* `-in, --include-hotkeys TEXT`: Hotkeys to include. Specify by name or ss58 address. If left empty, all hotkeys, except those in the '--exclude-hotkeys', will be included. -* `-ex, --exclude-hotkeys TEXT`: Hotkeys to exclude. Specify by name or ss58 address. If left empty, all hotkeys, except those in the '--include-hotkeys', will be excluded. -* `-n, --netuids, --netuid TEXT`: Set the netuid(s) to exclude. Separate multiple netuids with a comma, for example: `-n 0,1,2`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet transfer` - -Send TAO tokens from one wallet to another wallet on the Bittensor network. - -This command is used for transactions between different wallet accounts, enabling users to send tokens to other -participants on the network. The command displays the user's current balance before prompting for the amount -to transfer (send), ensuring transparency and accuracy in the transaction. - -**Usage:** - -The command requires that you specify the destination address (public key) and the amount of TAO you want transferred. -It checks if sufficient balance exists in your wallet and prompts for confirmation before proceeding with the transaction. - -**Example:** - -``` -btcli wallet transfer --dest 5Dp8... --amount 100 -``` - -Note: This command is used for executing token transfers within the Bittensor network. Users should verify the destination address and the TAO amount before confirming the transaction to avoid errors or loss of funds. - -**Usage**: - -```console -btcli wallet transfer [OPTIONS] -``` - -**Options**: - -* `-d, --destination, --dest TEXT`: Destination address (ss58) of the wallet (coldkey). -* `-a, --amount FLOAT`: Amount (in TAO) to transfer. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet inspect` - -Displays the details of the user's wallet pairs (coldkey, hotkey) on the Bittensor network. - -The output is presented as a table with the below columns: - -- Coldkey: The coldkey associated with the user's wallet. - -- Balance: The balance of the coldkey. - -- Delegate: The name of the delegate to which the coldkey has staked TAO. - -- Stake: The amount of stake held by both the coldkey and hotkey. - -- Emission: The emission or rewards earned from staking. - -- Netuid: The network unique identifier of the subnet where the hotkey is active (i.e., validating). - -- Hotkey: The hotkey associated with the neuron on the network. - -**Usage:** - -This command can be used to inspect a single wallet or all the wallets located at a specified path. It is useful for a comprehensive overview of a user's participation and performance in the Bittensor network. - -**Example:** - -``` -btcli wallet inspect -``` - -``` -btcli wallet inspect --all -n 1 -n 2 -n 3 -``` - -Note: The `inspect` command is for displaying information only and does not perform any transactions or state changes on the blockchain. It is intended to be used with Bittensor CLI and not as a standalone function in user code. - -**Usage**: - -```console -btcli wallet inspect [OPTIONS] -``` - -**Options**: - -* `-a, --all, --all-wallets`: Inspect all the wallets at the specified wallet path. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `-n, --netuids, --netuid TEXT`: Set the netuid(s) to exclude. Separate multiple netuids with a comma, for example: `-n 0,1,2`. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet faucet` - -Obtain test TAO tokens by performing Proof of Work (PoW). - -This command is useful for users who need test tokens for operations on a local blockchain. - -**Important:**: THIS COMMAND IS DISABLED ON FINNEY AND TESTNET. - -**Usage:** - -The command uses the proof-of-work (POW) mechanism to validate the user's effort and rewards them with test TAO tokens. It is -typically used in local blockchain environments where transactions do not use real TAO tokens. - -**Example:** - -``` -btcli wallet faucet --faucet.num_processes 4 --faucet.cuda.use_cuda -``` - -Note: This command is meant for used in local environments where users can experiment with the blockchain without using real TAO tokens. Users must have the necessary hardware setup, especially when opting for CUDA-based GPU calculations. It is currently disabled on testnet and mainnet (finney). You can only use this command on a local blockchain. - -**Usage**: - -```console -btcli wallet faucet [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--processors INTEGER`: Number of processors to use for proof of work (POW) registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set flag to use CUDA for proof of work (POW) registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s) in the order of speed, where 0 is the fastest. [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--max-successes INTEGER`: Set the maximum number of times to successfully run the faucet for this command. [default: 3] -* `--help`: Show this message and exit. - -### `btcli wallet set-identity` - -Create or update the on-chain identity of a coldkey or a hotkey on the Bittensor network. Incurs a 1 TAO transaction fee. - -The on-chain identity includes attributes such as display name, legal name, web URL, PGP fingerprint, and contact information, among others. - -The command prompts the user for the identity attributes and validates the input size for each attribute. It provides an option to update an existing validator hotkey identity. If the user consents to the transaction cost, the identity is updated on the blockchain. - -Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey ``ss58`` address for the identity to be updated. - -If the user does not have a hotkey, the coldkey address is used by default. If setting a validator identity, the hotkey will be used by default. If the user is setting an identity for a subnet, the coldkey will be used by default. - -**Example:** - -``` -btcli wallet set_identity -``` - -Note: This command should only be used if the user is willing to incur the a recycle fee associated with setting an identity on the blockchain. It is a high-level command that makes changes to the blockchain state and should not be used programmatically as part of other scripts or applications. - -**Usage**: - -```console -btcli wallet set-identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--name TEXT`: The display name for the identity. -* `--web-url, --web TEXT`: The web URL for the identity. -* `--image-url, --image TEXT`: The image URL for the identity. -* `--discord TEXT`: The Discord handle for the identity. -* `--description TEXT`: The description for the identity. -* `--additional TEXT`: Additional details for the identity. -* `--github TEXT`: The GitHub repository for the identity. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli wallet get-identity` - -Shows the identity details of a user's coldkey or hotkey. - -The command displays the information in a table format showing: - -- Address: The ``ss58`` address of the queried key. - -- Item: Various attributes of the identity such as stake, rank, and trust. - -- Value: The corresponding values of the attributes. - -**Example:** - -``` -btcli wallet get_identity --key <s58_address> -``` - -Note: This command is primarily used for informational purposes and has no side effects on the blockchain network state. - -**Usage**: - -```console -btcli wallet get-identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-k, --ss58, --coldkey_ss58, --coldkey.ss58_address, --coldkey.ss58, --key TEXT`: Coldkey address of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet sign` - -Allows users to sign a message with the provided wallet or wallet hotkey. Use this command to easily prove your ownership of a coldkey or a hotkey. - -**Usage:** - -Using the provided wallet (coldkey), the command generates a signature for a given message. - -**Example:** - -``` -btcli wallet sign --wallet-name default --message '{"something": "here", "timestamp": 1719908486}' -``` - -``` -btcli wallet sign --wallet-name default --wallet-hotkey hotkey --message '{"something": "here", "timestamp": 1719908486}' -``` - -**Usage**: - -```console -btcli wallet sign [OPTIONS] -``` - -**Options**: - -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--use-hotkey / --no-use-hotkey`: If specified, the message will be signed by the hotkey. If not specified, the user will be prompted. -* `--message TEXT`: The message to encode and sign -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet swap_hotkey` - -Swap hotkeys of a given wallet on the blockchain. For a registered key pair, for example, a (coldkeyA, hotkeyA) pair, this command swaps the hotkeyA with a new, unregistered, hotkeyB to move the original registration to the (coldkeyA, hotkeyB) pair. - -**Usage:** - -The command is used to swap the hotkey of a wallet for another hotkey on that same wallet. - -**Important:** - -- Make sure that your original key pair (coldkeyA, hotkeyA) is already registered. -- Make sure that you use a newly created hotkeyB in this command. A hotkeyB that is already registered cannot be used in this command. -- Finally, note that this command requires a fee of 1 TAO for recycling and this fee is taken from your wallet (coldkeyA). - -**Example:** - -``` -btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey -``` - -**Usage**: - -```console -btcli wallet swap_hotkey [OPTIONS] [DESTINATION_HOTKEY_NAME] -``` - -**Arguments**: - -* `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli wallet regen_coldkey` - -Regenerate a coldkey for a wallet on the Bittensor blockchain network. - -This command is used to create a new coldkey from an existing mnemonic, seed, or JSON file. - -**Usage:** - -Users can specify a mnemonic, a seed string, or a JSON file path to regenerate a coldkey. The command supports optional password protection for the generated key. - -**Example:** - -``` -btcli wallet regen-coldkey --mnemonic "word1 word2 ... word12" -``` - - -Note: This command is critical for users who need to regenerate their coldkey either for recovery or for security reasons. - -**Usage**: - -```console -btcli wallet regen_coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet regen_coldkeypub` - -Regenerates the public part of a coldkey (coldkeypub.txt) for a wallet. - -Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your coldkeypub.txt that you have on another machine to regenerate the coldkeypub.txt on this new machine. - -**Usage:** - -The command requires either a public key in hexadecimal format or an ``SS58`` address from the existing coldkeypub.txt from old machine to regenerate the coldkeypub on the new machine. - -**Example:** - -``` -btcli wallet regen_coldkeypub --ss58_address 5DkQ4... -``` - -Note: This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old coldkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. - -**Usage**: - -```console -btcli wallet regen_coldkeypub [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--public-key-hex TEXT`: The public key in hex format. -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet regen_hotkey` - -Regenerates a hotkey for a wallet. - -Similar to regenerating a coldkey, this command creates a new hotkey from a mnemonic, seed, or JSON file. - -**Usage:** - -Users can provide a mnemonic, seed string, or a JSON file to regenerate the hotkey. The command supports optional password protection and can overwrite an existing hotkey. - - -``` -btcli wallet regen_hotkey --seed 0x1234... -``` - -Note: This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery. -It should be used with caution to avoid accidental overwriting of existing keys. - -**Usage**: - -```console -btcli wallet regen_hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet new_hotkey` - -Create a new hotkey for a wallet. - -**Usage:** - -This command is used to generate a new hotkey for managing a neuron or participating in a subnet. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting the -existing hotkey. - -**Example:** - -``` -btcli wallet new-hotkey --n_words 24 -``` - -Note: This command is useful to create additional hotkeys for different purposes, such as running multiple subnet miners or subnet validators or separating operational roles within the Bittensor network. - -**Usage**: - -```console -btcli wallet new_hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet new_coldkey` - -Create a new coldkey. A coldkey is required for holding TAO balances and performing high-value transactions. - -**Usage:** - -The command creates a new coldkey. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting an existing coldkey. - -**Example:** - -``` -btcli wallet new_coldkey --n_words 15 -``` - -Note: This command is crucial for users who need to create a new coldkey for enhanced security or as part of setting up a new wallet. It is a foundational step in establishing a secure presence on the Bittensor network. - -**Usage**: - -```console -btcli wallet new_coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallet set_identity` - -Create or update the on-chain identity of a coldkey or a hotkey on the Bittensor network. Incurs a 1 TAO transaction fee. - -The on-chain identity includes attributes such as display name, legal name, web URL, PGP fingerprint, and contact information, among others. - -The command prompts the user for the identity attributes and validates the input size for each attribute. It provides an option to update an existing validator hotkey identity. If the user consents to the transaction cost, the identity is updated on the blockchain. - -Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey ``ss58`` address for the identity to be updated. - -If the user does not have a hotkey, the coldkey address is used by default. If setting a validator identity, the hotkey will be used by default. If the user is setting an identity for a subnet, the coldkey will be used by default. - -**Example:** - -``` -btcli wallet set_identity -``` - -Note: This command should only be used if the user is willing to incur the a recycle fee associated with setting an identity on the blockchain. It is a high-level command that makes changes to the blockchain state and should not be used programmatically as part of other scripts or applications. - -**Usage**: - -```console -btcli wallet set_identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--name TEXT`: The display name for the identity. -* `--web-url, --web TEXT`: The web URL for the identity. -* `--image-url, --image TEXT`: The image URL for the identity. -* `--discord TEXT`: The Discord handle for the identity. -* `--description TEXT`: The description for the identity. -* `--additional TEXT`: Additional details for the identity. -* `--github TEXT`: The GitHub repository for the identity. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli wallet get_identity` - -Shows the identity details of a user's coldkey or hotkey. - -The command displays the information in a table format showing: - -- Address: The ``ss58`` address of the queried key. - -- Item: Various attributes of the identity such as stake, rank, and trust. - -- Value: The corresponding values of the attributes. - -**Example:** - -``` -btcli wallet get_identity --key <s58_address> -``` - -Note: This command is primarily used for informational purposes and has no side effects on the blockchain network state. - -**Usage**: - -```console -btcli wallet get_identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-k, --ss58, --coldkey_ss58, --coldkey.ss58_address, --coldkey.ss58, --key TEXT`: Coldkey address of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli w` - -**Usage**: - -```console -btcli w [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `list`: Displays all the wallets and their... -* `swap-hotkey`: Swap hotkeys of a given wallet on the... -* `regen-coldkey`: Regenerate a coldkey for a wallet on the... -* `regen-coldkeypub`: Regenerates the public part of a coldkey... -* `regen-hotkey`: Regenerates a hotkey for a wallet. -* `new-hotkey`: Create a new hotkey for a wallet. -* `new-coldkey`: Create a new coldkey. -* `create`: Create a complete wallet by setting up... -* `balance`: Check the balance of the wallet. -* `history`: Show the history of the transfers carried... -* `overview`: Displays a detailed overview of the user's... -* `transfer`: Send TAO tokens from one wallet to another... -* `inspect`: Displays the details of the user's wallet... -* `faucet`: Obtain test TAO tokens by performing Proof... -* `set-identity`: Create or update the on-chain identity of... -* `get-identity`: Shows the identity details of a user's... -* `sign`: Allows users to sign a message with the... -* `swap_hotkey`: Swap hotkeys of a given wallet on the... -* `regen_coldkey`: Regenerate a coldkey for a wallet on the... -* `regen_coldkeypub`: Regenerates the public part of a coldkey... -* `regen_hotkey`: Regenerates a hotkey for a wallet. -* `new_hotkey`: Create a new hotkey for a wallet. -* `new_coldkey`: Create a new coldkey. -* `set_identity`: Create or update the on-chain identity of... -* `get_identity`: Shows the identity details of a user's... - -### `btcli w list` - -Displays all the wallets and their corresponding hotkeys that are located in the wallet path specified in the config. - -The output display shows each wallet and its associated `ss58` addresses for the coldkey public key and any hotkeys. The output is presented in a hierarchical tree format, with each wallet as a root node and any associated hotkeys as child nodes. The `ss58` address is displayed for each coldkey and hotkey that is not encrypted and exists on the device. - -Upon invocation, the command scans the wallet directory and prints a list of all the wallets, indicating whether the -public keys are available (`?` denotes unavailable or encrypted keys). - - -``` -btcli wallet list --path ~/.bittensor -``` - -Note: This command is read-only and does not modify the filesystem or the blockchain state. It is intended for use with the Bittensor CLI to provide a quick overview of the user's wallets. - -**Usage**: - -```console -btcli w list [OPTIONS] -``` - -**Options**: - -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w swap-hotkey` - -Swap hotkeys of a given wallet on the blockchain. For a registered key pair, for example, a (coldkeyA, hotkeyA) pair, this command swaps the hotkeyA with a new, unregistered, hotkeyB to move the original registration to the (coldkeyA, hotkeyB) pair. - -**Usage:** - -The command is used to swap the hotkey of a wallet for another hotkey on that same wallet. - -**Important:** - -- Make sure that your original key pair (coldkeyA, hotkeyA) is already registered. -- Make sure that you use a newly created hotkeyB in this command. A hotkeyB that is already registered cannot be used in this command. -- Finally, note that this command requires a fee of 1 TAO for recycling and this fee is taken from your wallet (coldkeyA). - -**Example:** - -``` -btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey -``` - -**Usage**: - -```console -btcli w swap-hotkey [OPTIONS] [DESTINATION_HOTKEY_NAME] -``` - -**Arguments**: - -* `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli w regen-coldkey` - -Regenerate a coldkey for a wallet on the Bittensor blockchain network. - -This command is used to create a new coldkey from an existing mnemonic, seed, or JSON file. - -**Usage:** - -Users can specify a mnemonic, a seed string, or a JSON file path to regenerate a coldkey. The command supports optional password protection for the generated key. - -**Example:** - -``` -btcli wallet regen-coldkey --mnemonic "word1 word2 ... word12" -``` - - -Note: This command is critical for users who need to regenerate their coldkey either for recovery or for security reasons. - -**Usage**: - -```console -btcli w regen-coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w regen-coldkeypub` - -Regenerates the public part of a coldkey (coldkeypub.txt) for a wallet. - -Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your coldkeypub.txt that you have on another machine to regenerate the coldkeypub.txt on this new machine. - -**Usage:** - -The command requires either a public key in hexadecimal format or an ``SS58`` address from the existing coldkeypub.txt from old machine to regenerate the coldkeypub on the new machine. - -**Example:** - -``` -btcli wallet regen_coldkeypub --ss58_address 5DkQ4... -``` - -Note: This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old coldkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. - -**Usage**: - -```console -btcli w regen-coldkeypub [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--public-key-hex TEXT`: The public key in hex format. -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w regen-hotkey` - -Regenerates a hotkey for a wallet. - -Similar to regenerating a coldkey, this command creates a new hotkey from a mnemonic, seed, or JSON file. - -**Usage:** - -Users can provide a mnemonic, seed string, or a JSON file to regenerate the hotkey. The command supports optional password protection and can overwrite an existing hotkey. - - -``` -btcli wallet regen_hotkey --seed 0x1234... -``` - -Note: This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery. -It should be used with caution to avoid accidental overwriting of existing keys. - -**Usage**: - -```console -btcli w regen-hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w new-hotkey` - -Create a new hotkey for a wallet. - -**Usage:** - -This command is used to generate a new hotkey for managing a neuron or participating in a subnet. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting the -existing hotkey. - -**Example:** - -``` -btcli wallet new-hotkey --n_words 24 -``` - -Note: This command is useful to create additional hotkeys for different purposes, such as running multiple subnet miners or subnet validators or separating operational roles within the Bittensor network. - -**Usage**: - -```console -btcli w new-hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w new-coldkey` - -Create a new coldkey. A coldkey is required for holding TAO balances and performing high-value transactions. - -**Usage:** - -The command creates a new coldkey. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting an existing coldkey. - -**Example:** - -``` -btcli wallet new_coldkey --n_words 15 -``` - -Note: This command is crucial for users who need to create a new coldkey for enhanced security or as part of setting up a new wallet. It is a foundational step in establishing a secure presence on the Bittensor network. - -**Usage**: - -```console -btcli w new-coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w create` - -Create a complete wallet by setting up both coldkey and hotkeys. - -**Usage:** - -The command creates a new coldkey and hotkey. It provides an option for mnemonic word count. It supports password protection for the coldkey and allows overwriting of existing keys. - -**Example:** - -``` -btcli wallet create --n_words 21 -``` - -Note: This command is for new users setting up their wallet for the first time, or for those who wish to completely renew their wallet keys. It ensures a fresh start with new keys for secure and effective participation in the Bittensor network. - -**Usage**: - -```console -btcli w create [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words INTEGER` -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w balance` - -Check the balance of the wallet. This command shows a detailed view of the wallet's coldkey balances, including free and staked balances. - -You can also pass multiple ss58 addresses of coldkeys to check their balance (using --ss58). - -**Example:** - -- To display the balance of a single wallet, use the command with the `--wallet-name` argument and provide the wallet name: - - ``` - btcli w balance --wallet-name WALLET - ``` - -- To use the default config values, use: - - ``` - btcli w balance - ``` - -- To display the balances of all your wallets, use the `--all` argument: - - ``` - btcli w balance --all - ``` - -- To display the balances of ss58 addresses, use the `--ss58` argument: - - ``` - btcli w balance --ss58 <ss58_address> --ss58 <ss58_address> - ``` - -**Usage**: - -```console -btcli w balance [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `-a, --all`: Whether to display the balances for all the wallets. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w history` - -Show the history of the transfers carried out with the provided wallet on the Bittensor network. - -**Usage:** - -The output shows the latest transfers of the provided wallet, showing the columns 'From', 'To', 'Amount', 'Extrinsic ID' and 'Block Number'. - -**Example:** - -``` -btcli wallet history -``` - -**Usage**: - -```console -btcli w history [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w overview` - -Displays a detailed overview of the user's registered accounts on the Bittensor network. - -This command compiles and displays comprehensive information about each neuron associated with the user's wallets, including both hotkeys and coldkeys. It is especially useful for users managing multiple accounts or looking for a summary of their network activities and stake distributions. - -**Usage:** - -``` -btcli wallet overview -``` - -``` -btcli wallet overview --all -``` - -Note: This command is read-only and does not modify the blockchain state or account configuration. -It provides a quick and comprehensive view of the user's network presence, making it useful for monitoring account status, -stake distribution, and overall contribution to the Bittensor network. - -**Usage**: - -```console -btcli w overview [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-a, --all`: See an overview for all the wallets -* `--sort-by, --sort_by TEXT`: Sort the hotkeys by the specified column title. For example: name, uid, axon. -* `--sort-order, --sort_order TEXT`: Sort the hotkeys in the specified order (ascending/asc or descending/desc/reverse). -* `-in, --include-hotkeys TEXT`: Hotkeys to include. Specify by name or ss58 address. If left empty, all hotkeys, except those in the '--exclude-hotkeys', will be included. -* `-ex, --exclude-hotkeys TEXT`: Hotkeys to exclude. Specify by name or ss58 address. If left empty, all hotkeys, except those in the '--include-hotkeys', will be excluded. -* `-n, --netuids, --netuid TEXT`: Set the netuid(s) to exclude. Separate multiple netuids with a comma, for example: `-n 0,1,2`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w transfer` - -Send TAO tokens from one wallet to another wallet on the Bittensor network. - -This command is used for transactions between different wallet accounts, enabling users to send tokens to other -participants on the network. The command displays the user's current balance before prompting for the amount -to transfer (send), ensuring transparency and accuracy in the transaction. - -**Usage:** - -The command requires that you specify the destination address (public key) and the amount of TAO you want transferred. -It checks if sufficient balance exists in your wallet and prompts for confirmation before proceeding with the transaction. - -**Example:** - -``` -btcli wallet transfer --dest 5Dp8... --amount 100 -``` - -Note: This command is used for executing token transfers within the Bittensor network. Users should verify the destination address and the TAO amount before confirming the transaction to avoid errors or loss of funds. - -**Usage**: - -```console -btcli w transfer [OPTIONS] -``` - -**Options**: - -* `-d, --destination, --dest TEXT`: Destination address (ss58) of the wallet (coldkey). -* `-a, --amount FLOAT`: Amount (in TAO) to transfer. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w inspect` - -Displays the details of the user's wallet pairs (coldkey, hotkey) on the Bittensor network. - -The output is presented as a table with the below columns: - -- Coldkey: The coldkey associated with the user's wallet. - -- Balance: The balance of the coldkey. - -- Delegate: The name of the delegate to which the coldkey has staked TAO. - -- Stake: The amount of stake held by both the coldkey and hotkey. - -- Emission: The emission or rewards earned from staking. - -- Netuid: The network unique identifier of the subnet where the hotkey is active (i.e., validating). - -- Hotkey: The hotkey associated with the neuron on the network. - -**Usage:** - -This command can be used to inspect a single wallet or all the wallets located at a specified path. It is useful for a comprehensive overview of a user's participation and performance in the Bittensor network. - -**Example:** - -``` -btcli wallet inspect -``` - -``` -btcli wallet inspect --all -n 1 -n 2 -n 3 -``` - -Note: The `inspect` command is for displaying information only and does not perform any transactions or state changes on the blockchain. It is intended to be used with Bittensor CLI and not as a standalone function in user code. - -**Usage**: - -```console -btcli w inspect [OPTIONS] -``` - -**Options**: - -* `-a, --all, --all-wallets`: Inspect all the wallets at the specified wallet path. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `-n, --netuids, --netuid TEXT`: Set the netuid(s) to exclude. Separate multiple netuids with a comma, for example: `-n 0,1,2`. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w faucet` - -Obtain test TAO tokens by performing Proof of Work (PoW). - -This command is useful for users who need test tokens for operations on a local blockchain. - -**Important:**: THIS COMMAND IS DISABLED ON FINNEY AND TESTNET. - -**Usage:** - -The command uses the proof-of-work (POW) mechanism to validate the user's effort and rewards them with test TAO tokens. It is -typically used in local blockchain environments where transactions do not use real TAO tokens. - -**Example:** - -``` -btcli wallet faucet --faucet.num_processes 4 --faucet.cuda.use_cuda -``` - -Note: This command is meant for used in local environments where users can experiment with the blockchain without using real TAO tokens. Users must have the necessary hardware setup, especially when opting for CUDA-based GPU calculations. It is currently disabled on testnet and mainnet (finney). You can only use this command on a local blockchain. - -**Usage**: - -```console -btcli w faucet [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--processors INTEGER`: Number of processors to use for proof of work (POW) registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set flag to use CUDA for proof of work (POW) registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s) in the order of speed, where 0 is the fastest. [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--max-successes INTEGER`: Set the maximum number of times to successfully run the faucet for this command. [default: 3] -* `--help`: Show this message and exit. - -### `btcli w set-identity` - -Create or update the on-chain identity of a coldkey or a hotkey on the Bittensor network. Incurs a 1 TAO transaction fee. - -The on-chain identity includes attributes such as display name, legal name, web URL, PGP fingerprint, and contact information, among others. - -The command prompts the user for the identity attributes and validates the input size for each attribute. It provides an option to update an existing validator hotkey identity. If the user consents to the transaction cost, the identity is updated on the blockchain. - -Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey ``ss58`` address for the identity to be updated. - -If the user does not have a hotkey, the coldkey address is used by default. If setting a validator identity, the hotkey will be used by default. If the user is setting an identity for a subnet, the coldkey will be used by default. - -**Example:** - -``` -btcli wallet set_identity -``` - -Note: This command should only be used if the user is willing to incur the a recycle fee associated with setting an identity on the blockchain. It is a high-level command that makes changes to the blockchain state and should not be used programmatically as part of other scripts or applications. - -**Usage**: - -```console -btcli w set-identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--name TEXT`: The display name for the identity. -* `--web-url, --web TEXT`: The web URL for the identity. -* `--image-url, --image TEXT`: The image URL for the identity. -* `--discord TEXT`: The Discord handle for the identity. -* `--description TEXT`: The description for the identity. -* `--additional TEXT`: Additional details for the identity. -* `--github TEXT`: The GitHub repository for the identity. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli w get-identity` - -Shows the identity details of a user's coldkey or hotkey. - -The command displays the information in a table format showing: - -- Address: The ``ss58`` address of the queried key. - -- Item: Various attributes of the identity such as stake, rank, and trust. - -- Value: The corresponding values of the attributes. - -**Example:** - -``` -btcli wallet get_identity --key <s58_address> -``` - -Note: This command is primarily used for informational purposes and has no side effects on the blockchain network state. - -**Usage**: - -```console -btcli w get-identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-k, --ss58, --coldkey_ss58, --coldkey.ss58_address, --coldkey.ss58, --key TEXT`: Coldkey address of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w sign` - -Allows users to sign a message with the provided wallet or wallet hotkey. Use this command to easily prove your ownership of a coldkey or a hotkey. - -**Usage:** - -Using the provided wallet (coldkey), the command generates a signature for a given message. - -**Example:** - -``` -btcli wallet sign --wallet-name default --message '{"something": "here", "timestamp": 1719908486}' -``` - -``` -btcli wallet sign --wallet-name default --wallet-hotkey hotkey --message '{"something": "here", "timestamp": 1719908486}' -``` - -**Usage**: - -```console -btcli w sign [OPTIONS] -``` - -**Options**: - -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--use-hotkey / --no-use-hotkey`: If specified, the message will be signed by the hotkey. If not specified, the user will be prompted. -* `--message TEXT`: The message to encode and sign -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w swap_hotkey` - -Swap hotkeys of a given wallet on the blockchain. For a registered key pair, for example, a (coldkeyA, hotkeyA) pair, this command swaps the hotkeyA with a new, unregistered, hotkeyB to move the original registration to the (coldkeyA, hotkeyB) pair. - -**Usage:** - -The command is used to swap the hotkey of a wallet for another hotkey on that same wallet. - -**Important:** - -- Make sure that your original key pair (coldkeyA, hotkeyA) is already registered. -- Make sure that you use a newly created hotkeyB in this command. A hotkeyB that is already registered cannot be used in this command. -- Finally, note that this command requires a fee of 1 TAO for recycling and this fee is taken from your wallet (coldkeyA). - -**Example:** - -``` -btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey -``` - -**Usage**: - -```console -btcli w swap_hotkey [OPTIONS] [DESTINATION_HOTKEY_NAME] -``` - -**Arguments**: - -* `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli w regen_coldkey` - -Regenerate a coldkey for a wallet on the Bittensor blockchain network. - -This command is used to create a new coldkey from an existing mnemonic, seed, or JSON file. - -**Usage:** - -Users can specify a mnemonic, a seed string, or a JSON file path to regenerate a coldkey. The command supports optional password protection for the generated key. - -**Example:** - -``` -btcli wallet regen-coldkey --mnemonic "word1 word2 ... word12" -``` - - -Note: This command is critical for users who need to regenerate their coldkey either for recovery or for security reasons. - -**Usage**: - -```console -btcli w regen_coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w regen_coldkeypub` - -Regenerates the public part of a coldkey (coldkeypub.txt) for a wallet. - -Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your coldkeypub.txt that you have on another machine to regenerate the coldkeypub.txt on this new machine. - -**Usage:** - -The command requires either a public key in hexadecimal format or an ``SS58`` address from the existing coldkeypub.txt from old machine to regenerate the coldkeypub on the new machine. - -**Example:** - -``` -btcli wallet regen_coldkeypub --ss58_address 5DkQ4... -``` - -Note: This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old coldkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. - -**Usage**: - -```console -btcli w regen_coldkeypub [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--public-key-hex TEXT`: The public key in hex format. -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w regen_hotkey` - -Regenerates a hotkey for a wallet. - -Similar to regenerating a coldkey, this command creates a new hotkey from a mnemonic, seed, or JSON file. - -**Usage:** - -Users can provide a mnemonic, seed string, or a JSON file to regenerate the hotkey. The command supports optional password protection and can overwrite an existing hotkey. - - -``` -btcli wallet regen_hotkey --seed 0x1234... -``` - -Note: This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery. -It should be used with caution to avoid accidental overwriting of existing keys. - -**Usage**: - -```console -btcli w regen_hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w new_hotkey` - -Create a new hotkey for a wallet. - -**Usage:** - -This command is used to generate a new hotkey for managing a neuron or participating in a subnet. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting the -existing hotkey. - -**Example:** - -``` -btcli wallet new-hotkey --n_words 24 -``` - -Note: This command is useful to create additional hotkeys for different purposes, such as running multiple subnet miners or subnet validators or separating operational roles within the Bittensor network. - -**Usage**: - -```console -btcli w new_hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w new_coldkey` - -Create a new coldkey. A coldkey is required for holding TAO balances and performing high-value transactions. - -**Usage:** - -The command creates a new coldkey. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting an existing coldkey. - -**Example:** - -``` -btcli wallet new_coldkey --n_words 15 -``` - -Note: This command is crucial for users who need to create a new coldkey for enhanced security or as part of setting up a new wallet. It is a foundational step in establishing a secure presence on the Bittensor network. - -**Usage**: - -```console -btcli w new_coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli w set_identity` - -Create or update the on-chain identity of a coldkey or a hotkey on the Bittensor network. Incurs a 1 TAO transaction fee. - -The on-chain identity includes attributes such as display name, legal name, web URL, PGP fingerprint, and contact information, among others. - -The command prompts the user for the identity attributes and validates the input size for each attribute. It provides an option to update an existing validator hotkey identity. If the user consents to the transaction cost, the identity is updated on the blockchain. - -Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey ``ss58`` address for the identity to be updated. - -If the user does not have a hotkey, the coldkey address is used by default. If setting a validator identity, the hotkey will be used by default. If the user is setting an identity for a subnet, the coldkey will be used by default. - -**Example:** - -``` -btcli wallet set_identity -``` - -Note: This command should only be used if the user is willing to incur the a recycle fee associated with setting an identity on the blockchain. It is a high-level command that makes changes to the blockchain state and should not be used programmatically as part of other scripts or applications. - -**Usage**: - -```console -btcli w set_identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--name TEXT`: The display name for the identity. -* `--web-url, --web TEXT`: The web URL for the identity. -* `--image-url, --image TEXT`: The image URL for the identity. -* `--discord TEXT`: The Discord handle for the identity. -* `--description TEXT`: The description for the identity. -* `--additional TEXT`: Additional details for the identity. -* `--github TEXT`: The GitHub repository for the identity. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli w get_identity` - -Shows the identity details of a user's coldkey or hotkey. - -The command displays the information in a table format showing: - -- Address: The ``ss58`` address of the queried key. - -- Item: Various attributes of the identity such as stake, rank, and trust. - -- Value: The corresponding values of the attributes. - -**Example:** - -``` -btcli wallet get_identity --key <s58_address> -``` - -Note: This command is primarily used for informational purposes and has no side effects on the blockchain network state. - -**Usage**: - -```console -btcli w get_identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-k, --ss58, --coldkey_ss58, --coldkey.ss58_address, --coldkey.ss58, --key TEXT`: Coldkey address of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli wallets` - -**Usage**: - -```console -btcli wallets [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `list`: Displays all the wallets and their... -* `swap-hotkey`: Swap hotkeys of a given wallet on the... -* `regen-coldkey`: Regenerate a coldkey for a wallet on the... -* `regen-coldkeypub`: Regenerates the public part of a coldkey... -* `regen-hotkey`: Regenerates a hotkey for a wallet. -* `new-hotkey`: Create a new hotkey for a wallet. -* `new-coldkey`: Create a new coldkey. -* `create`: Create a complete wallet by setting up... -* `balance`: Check the balance of the wallet. -* `history`: Show the history of the transfers carried... -* `overview`: Displays a detailed overview of the user's... -* `transfer`: Send TAO tokens from one wallet to another... -* `inspect`: Displays the details of the user's wallet... -* `faucet`: Obtain test TAO tokens by performing Proof... -* `set-identity`: Create or update the on-chain identity of... -* `get-identity`: Shows the identity details of a user's... -* `sign`: Allows users to sign a message with the... -* `swap_hotkey`: Swap hotkeys of a given wallet on the... -* `regen_coldkey`: Regenerate a coldkey for a wallet on the... -* `regen_coldkeypub`: Regenerates the public part of a coldkey... -* `regen_hotkey`: Regenerates a hotkey for a wallet. -* `new_hotkey`: Create a new hotkey for a wallet. -* `new_coldkey`: Create a new coldkey. -* `set_identity`: Create or update the on-chain identity of... -* `get_identity`: Shows the identity details of a user's... - -### `btcli wallets list` - -Displays all the wallets and their corresponding hotkeys that are located in the wallet path specified in the config. - -The output display shows each wallet and its associated `ss58` addresses for the coldkey public key and any hotkeys. The output is presented in a hierarchical tree format, with each wallet as a root node and any associated hotkeys as child nodes. The `ss58` address is displayed for each coldkey and hotkey that is not encrypted and exists on the device. - -Upon invocation, the command scans the wallet directory and prints a list of all the wallets, indicating whether the -public keys are available (`?` denotes unavailable or encrypted keys). - - -``` -btcli wallet list --path ~/.bittensor -``` - -Note: This command is read-only and does not modify the filesystem or the blockchain state. It is intended for use with the Bittensor CLI to provide a quick overview of the user's wallets. - -**Usage**: - -```console -btcli wallets list [OPTIONS] -``` - -**Options**: - -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets swap-hotkey` - -Swap hotkeys of a given wallet on the blockchain. For a registered key pair, for example, a (coldkeyA, hotkeyA) pair, this command swaps the hotkeyA with a new, unregistered, hotkeyB to move the original registration to the (coldkeyA, hotkeyB) pair. - -**Usage:** - -The command is used to swap the hotkey of a wallet for another hotkey on that same wallet. - -**Important:** - -- Make sure that your original key pair (coldkeyA, hotkeyA) is already registered. -- Make sure that you use a newly created hotkeyB in this command. A hotkeyB that is already registered cannot be used in this command. -- Finally, note that this command requires a fee of 1 TAO for recycling and this fee is taken from your wallet (coldkeyA). - -**Example:** - -``` -btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey -``` - -**Usage**: - -```console -btcli wallets swap-hotkey [OPTIONS] [DESTINATION_HOTKEY_NAME] -``` - -**Arguments**: - -* `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli wallets regen-coldkey` - -Regenerate a coldkey for a wallet on the Bittensor blockchain network. - -This command is used to create a new coldkey from an existing mnemonic, seed, or JSON file. - -**Usage:** - -Users can specify a mnemonic, a seed string, or a JSON file path to regenerate a coldkey. The command supports optional password protection for the generated key. - -**Example:** - -``` -btcli wallet regen-coldkey --mnemonic "word1 word2 ... word12" -``` - - -Note: This command is critical for users who need to regenerate their coldkey either for recovery or for security reasons. - -**Usage**: - -```console -btcli wallets regen-coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets regen-coldkeypub` - -Regenerates the public part of a coldkey (coldkeypub.txt) for a wallet. - -Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your coldkeypub.txt that you have on another machine to regenerate the coldkeypub.txt on this new machine. - -**Usage:** - -The command requires either a public key in hexadecimal format or an ``SS58`` address from the existing coldkeypub.txt from old machine to regenerate the coldkeypub on the new machine. - -**Example:** - -``` -btcli wallet regen_coldkeypub --ss58_address 5DkQ4... -``` - -Note: This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old coldkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. - -**Usage**: - -```console -btcli wallets regen-coldkeypub [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--public-key-hex TEXT`: The public key in hex format. -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets regen-hotkey` - -Regenerates a hotkey for a wallet. - -Similar to regenerating a coldkey, this command creates a new hotkey from a mnemonic, seed, or JSON file. - -**Usage:** - -Users can provide a mnemonic, seed string, or a JSON file to regenerate the hotkey. The command supports optional password protection and can overwrite an existing hotkey. - - -``` -btcli wallet regen_hotkey --seed 0x1234... -``` - -Note: This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery. -It should be used with caution to avoid accidental overwriting of existing keys. - -**Usage**: - -```console -btcli wallets regen-hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets new-hotkey` - -Create a new hotkey for a wallet. - -**Usage:** - -This command is used to generate a new hotkey for managing a neuron or participating in a subnet. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting the -existing hotkey. - -**Example:** - -``` -btcli wallet new-hotkey --n_words 24 -``` - -Note: This command is useful to create additional hotkeys for different purposes, such as running multiple subnet miners or subnet validators or separating operational roles within the Bittensor network. - -**Usage**: - -```console -btcli wallets new-hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets new-coldkey` - -Create a new coldkey. A coldkey is required for holding TAO balances and performing high-value transactions. - -**Usage:** - -The command creates a new coldkey. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting an existing coldkey. - -**Example:** - -``` -btcli wallet new_coldkey --n_words 15 -``` - -Note: This command is crucial for users who need to create a new coldkey for enhanced security or as part of setting up a new wallet. It is a foundational step in establishing a secure presence on the Bittensor network. - -**Usage**: - -```console -btcli wallets new-coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets create` - -Create a complete wallet by setting up both coldkey and hotkeys. - -**Usage:** - -The command creates a new coldkey and hotkey. It provides an option for mnemonic word count. It supports password protection for the coldkey and allows overwriting of existing keys. - -**Example:** - -``` -btcli wallet create --n_words 21 -``` - -Note: This command is for new users setting up their wallet for the first time, or for those who wish to completely renew their wallet keys. It ensures a fresh start with new keys for secure and effective participation in the Bittensor network. - -**Usage**: - -```console -btcli wallets create [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words INTEGER` -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets balance` - -Check the balance of the wallet. This command shows a detailed view of the wallet's coldkey balances, including free and staked balances. - -You can also pass multiple ss58 addresses of coldkeys to check their balance (using --ss58). - -**Example:** - -- To display the balance of a single wallet, use the command with the `--wallet-name` argument and provide the wallet name: - - ``` - btcli w balance --wallet-name WALLET - ``` - -- To use the default config values, use: - - ``` - btcli w balance - ``` - -- To display the balances of all your wallets, use the `--all` argument: - - ``` - btcli w balance --all - ``` - -- To display the balances of ss58 addresses, use the `--ss58` argument: - - ``` - btcli w balance --ss58 <ss58_address> --ss58 <ss58_address> - ``` - -**Usage**: - -```console -btcli wallets balance [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `-a, --all`: Whether to display the balances for all the wallets. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets history` - -Show the history of the transfers carried out with the provided wallet on the Bittensor network. - -**Usage:** - -The output shows the latest transfers of the provided wallet, showing the columns 'From', 'To', 'Amount', 'Extrinsic ID' and 'Block Number'. - -**Example:** - -``` -btcli wallet history -``` - -**Usage**: - -```console -btcli wallets history [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets overview` - -Displays a detailed overview of the user's registered accounts on the Bittensor network. - -This command compiles and displays comprehensive information about each neuron associated with the user's wallets, including both hotkeys and coldkeys. It is especially useful for users managing multiple accounts or looking for a summary of their network activities and stake distributions. - -**Usage:** - -``` -btcli wallet overview -``` - -``` -btcli wallet overview --all -``` - -Note: This command is read-only and does not modify the blockchain state or account configuration. -It provides a quick and comprehensive view of the user's network presence, making it useful for monitoring account status, -stake distribution, and overall contribution to the Bittensor network. - -**Usage**: - -```console -btcli wallets overview [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-a, --all`: See an overview for all the wallets -* `--sort-by, --sort_by TEXT`: Sort the hotkeys by the specified column title. For example: name, uid, axon. -* `--sort-order, --sort_order TEXT`: Sort the hotkeys in the specified order (ascending/asc or descending/desc/reverse). -* `-in, --include-hotkeys TEXT`: Hotkeys to include. Specify by name or ss58 address. If left empty, all hotkeys, except those in the '--exclude-hotkeys', will be included. -* `-ex, --exclude-hotkeys TEXT`: Hotkeys to exclude. Specify by name or ss58 address. If left empty, all hotkeys, except those in the '--include-hotkeys', will be excluded. -* `-n, --netuids, --netuid TEXT`: Set the netuid(s) to exclude. Separate multiple netuids with a comma, for example: `-n 0,1,2`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets transfer` - -Send TAO tokens from one wallet to another wallet on the Bittensor network. - -This command is used for transactions between different wallet accounts, enabling users to send tokens to other -participants on the network. The command displays the user's current balance before prompting for the amount -to transfer (send), ensuring transparency and accuracy in the transaction. - -**Usage:** - -The command requires that you specify the destination address (public key) and the amount of TAO you want transferred. -It checks if sufficient balance exists in your wallet and prompts for confirmation before proceeding with the transaction. - -**Example:** - -``` -btcli wallet transfer --dest 5Dp8... --amount 100 -``` - -Note: This command is used for executing token transfers within the Bittensor network. Users should verify the destination address and the TAO amount before confirming the transaction to avoid errors or loss of funds. - -**Usage**: - -```console -btcli wallets transfer [OPTIONS] -``` - -**Options**: - -* `-d, --destination, --dest TEXT`: Destination address (ss58) of the wallet (coldkey). -* `-a, --amount FLOAT`: Amount (in TAO) to transfer. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets inspect` - -Displays the details of the user's wallet pairs (coldkey, hotkey) on the Bittensor network. - -The output is presented as a table with the below columns: - -- Coldkey: The coldkey associated with the user's wallet. - -- Balance: The balance of the coldkey. - -- Delegate: The name of the delegate to which the coldkey has staked TAO. - -- Stake: The amount of stake held by both the coldkey and hotkey. - -- Emission: The emission or rewards earned from staking. - -- Netuid: The network unique identifier of the subnet where the hotkey is active (i.e., validating). - -- Hotkey: The hotkey associated with the neuron on the network. - -**Usage:** - -This command can be used to inspect a single wallet or all the wallets located at a specified path. It is useful for a comprehensive overview of a user's participation and performance in the Bittensor network. - -**Example:** - -``` -btcli wallet inspect -``` - -``` -btcli wallet inspect --all -n 1 -n 2 -n 3 -``` - -Note: The `inspect` command is for displaying information only and does not perform any transactions or state changes on the blockchain. It is intended to be used with Bittensor CLI and not as a standalone function in user code. - -**Usage**: - -```console -btcli wallets inspect [OPTIONS] -``` - -**Options**: - -* `-a, --all, --all-wallets`: Inspect all the wallets at the specified wallet path. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `-n, --netuids, --netuid TEXT`: Set the netuid(s) to exclude. Separate multiple netuids with a comma, for example: `-n 0,1,2`. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets faucet` - -Obtain test TAO tokens by performing Proof of Work (PoW). - -This command is useful for users who need test tokens for operations on a local blockchain. - -**Important:**: THIS COMMAND IS DISABLED ON FINNEY AND TESTNET. - -**Usage:** - -The command uses the proof-of-work (POW) mechanism to validate the user's effort and rewards them with test TAO tokens. It is -typically used in local blockchain environments where transactions do not use real TAO tokens. - -**Example:** - -``` -btcli wallet faucet --faucet.num_processes 4 --faucet.cuda.use_cuda -``` - -Note: This command is meant for used in local environments where users can experiment with the blockchain without using real TAO tokens. Users must have the necessary hardware setup, especially when opting for CUDA-based GPU calculations. It is currently disabled on testnet and mainnet (finney). You can only use this command on a local blockchain. - -**Usage**: - -```console -btcli wallets faucet [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--processors INTEGER`: Number of processors to use for proof of work (POW) registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set flag to use CUDA for proof of work (POW) registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s) in the order of speed, where 0 is the fastest. [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--max-successes INTEGER`: Set the maximum number of times to successfully run the faucet for this command. [default: 3] -* `--help`: Show this message and exit. - -### `btcli wallets set-identity` - -Create or update the on-chain identity of a coldkey or a hotkey on the Bittensor network. Incurs a 1 TAO transaction fee. - -The on-chain identity includes attributes such as display name, legal name, web URL, PGP fingerprint, and contact information, among others. - -The command prompts the user for the identity attributes and validates the input size for each attribute. It provides an option to update an existing validator hotkey identity. If the user consents to the transaction cost, the identity is updated on the blockchain. - -Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey ``ss58`` address for the identity to be updated. - -If the user does not have a hotkey, the coldkey address is used by default. If setting a validator identity, the hotkey will be used by default. If the user is setting an identity for a subnet, the coldkey will be used by default. - -**Example:** - -``` -btcli wallet set_identity -``` - -Note: This command should only be used if the user is willing to incur the a recycle fee associated with setting an identity on the blockchain. It is a high-level command that makes changes to the blockchain state and should not be used programmatically as part of other scripts or applications. - -**Usage**: - -```console -btcli wallets set-identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--name TEXT`: The display name for the identity. -* `--web-url, --web TEXT`: The web URL for the identity. -* `--image-url, --image TEXT`: The image URL for the identity. -* `--discord TEXT`: The Discord handle for the identity. -* `--description TEXT`: The description for the identity. -* `--additional TEXT`: Additional details for the identity. -* `--github TEXT`: The GitHub repository for the identity. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli wallets get-identity` - -Shows the identity details of a user's coldkey or hotkey. - -The command displays the information in a table format showing: - -- Address: The ``ss58`` address of the queried key. - -- Item: Various attributes of the identity such as stake, rank, and trust. - -- Value: The corresponding values of the attributes. - -**Example:** - -``` -btcli wallet get_identity --key <s58_address> -``` - -Note: This command is primarily used for informational purposes and has no side effects on the blockchain network state. - -**Usage**: - -```console -btcli wallets get-identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-k, --ss58, --coldkey_ss58, --coldkey.ss58_address, --coldkey.ss58, --key TEXT`: Coldkey address of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets sign` - -Allows users to sign a message with the provided wallet or wallet hotkey. Use this command to easily prove your ownership of a coldkey or a hotkey. - -**Usage:** - -Using the provided wallet (coldkey), the command generates a signature for a given message. - -**Example:** - -``` -btcli wallet sign --wallet-name default --message '{"something": "here", "timestamp": 1719908486}' -``` - -``` -btcli wallet sign --wallet-name default --wallet-hotkey hotkey --message '{"something": "here", "timestamp": 1719908486}' -``` - - -**Usage**: - -```console -btcli wallets sign [OPTIONS] -``` - -**Options**: - -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--use-hotkey / --no-use-hotkey`: If specified, the message will be signed by the hotkey. If not specified, the user will be prompted. -* `--message TEXT`: The message to encode and sign -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets swap_hotkey` - -Swap hotkeys of a given wallet on the blockchain. For a registered key pair, for example, a (coldkeyA, hotkeyA) pair, this command swaps the hotkeyA with a new, unregistered, hotkeyB to move the original registration to the (coldkeyA, hotkeyB) pair. - -**Usage:** - -The command is used to swap the hotkey of a wallet for another hotkey on that same wallet. - -**Important:** - -- Make sure that your original key pair (coldkeyA, hotkeyA) is already registered. -- Make sure that you use a newly created hotkeyB in this command. A hotkeyB that is already registered cannot be used in this command. -- Finally, note that this command requires a fee of 1 TAO for recycling and this fee is taken from your wallet (coldkeyA). - -**Example:** - -``` -btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey -``` - -**Usage**: - -```console -btcli wallets swap_hotkey [OPTIONS] [DESTINATION_HOTKEY_NAME] -``` - -**Arguments**: - -* `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli wallets regen_coldkey` - -Regenerate a coldkey for a wallet on the Bittensor blockchain network. - -This command is used to create a new coldkey from an existing mnemonic, seed, or JSON file. - -**Usage:** - -Users can specify a mnemonic, a seed string, or a JSON file path to regenerate a coldkey. The command supports optional password protection for the generated key. - -**Example:** - -``` -btcli wallet regen-coldkey --mnemonic "word1 word2 ... word12" -``` - - -Note: This command is critical for users who need to regenerate their coldkey either for recovery or for security reasons. - -**Usage**: - -```console -btcli wallets regen_coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets regen_coldkeypub` - -Regenerates the public part of a coldkey (coldkeypub.txt) for a wallet. - -Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your coldkeypub.txt that you have on another machine to regenerate the coldkeypub.txt on this new machine. - -**Usage:** - -The command requires either a public key in hexadecimal format or an ``SS58`` address from the existing coldkeypub.txt from old machine to regenerate the coldkeypub on the new machine. - -**Example:** - -``` -btcli wallet regen_coldkeypub --ss58_address 5DkQ4... -``` - -Note: This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old coldkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. - -**Usage**: - -```console -btcli wallets regen_coldkeypub [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--public-key-hex TEXT`: The public key in hex format. -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets regen_hotkey` - -Regenerates a hotkey for a wallet. - -Similar to regenerating a coldkey, this command creates a new hotkey from a mnemonic, seed, or JSON file. - -**Usage:** - -Users can provide a mnemonic, seed string, or a JSON file to regenerate the hotkey. The command supports optional password protection and can overwrite an existing hotkey. - - -``` -btcli wallet regen_hotkey --seed 0x1234... -``` - -Note: This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery. -It should be used with caution to avoid accidental overwriting of existing keys. - -**Usage**: - -```console -btcli wallets regen_hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets new_hotkey` - -Create a new hotkey for a wallet. - -**Usage:** - -This command is used to generate a new hotkey for managing a neuron or participating in a subnet. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting the -existing hotkey. - -**Example:** - -``` -btcli wallet new-hotkey --n_words 24 -``` - -Note: This command is useful to create additional hotkeys for different purposes, such as running multiple subnet miners or subnet validators or separating operational roles within the Bittensor network. - -**Usage**: - -```console -btcli wallets new_hotkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets new_coldkey` - -Create a new coldkey. A coldkey is required for holding TAO balances and performing high-value transactions. - -**Usage:** - -The command creates a new coldkey. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting an existing coldkey. - -**Example:** - -``` -btcli wallet new_coldkey --n_words 15 -``` - -Note: This command is crucial for users who need to create a new coldkey for enhanced security or as part of setting up a new wallet. It is a foundational step in establishing a secure presence on the Bittensor network. - -**Usage**: - -```console -btcli wallets new_coldkey [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--uri TEXT`: Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie', 'Dave', 'Eve') -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wallets set_identity` - -Create or update the on-chain identity of a coldkey or a hotkey on the Bittensor network. Incurs a 1 TAO transaction fee. - -The on-chain identity includes attributes such as display name, legal name, web URL, PGP fingerprint, and contact information, among others. - -The command prompts the user for the identity attributes and validates the input size for each attribute. It provides an option to update an existing validator hotkey identity. If the user consents to the transaction cost, the identity is updated on the blockchain. - -Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey ``ss58`` address for the identity to be updated. - -If the user does not have a hotkey, the coldkey address is used by default. If setting a validator identity, the hotkey will be used by default. If the user is setting an identity for a subnet, the coldkey will be used by default. - -**Example:** - -``` -btcli wallet set_identity -``` - -Note: This command should only be used if the user is willing to incur the a recycle fee associated with setting an identity on the blockchain. It is a high-level command that makes changes to the blockchain state and should not be used programmatically as part of other scripts or applications. - -**Usage**: - -```console -btcli wallets set_identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--name TEXT`: The display name for the identity. -* `--web-url, --web TEXT`: The web URL for the identity. -* `--image-url, --image TEXT`: The image URL for the identity. -* `--discord TEXT`: The Discord handle for the identity. -* `--description TEXT`: The description for the identity. -* `--additional TEXT`: Additional details for the identity. -* `--github TEXT`: The GitHub repository for the identity. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli wallets get_identity` - -Shows the identity details of a user's coldkey or hotkey. - -The command displays the information in a table format showing: - -- Address: The ``ss58`` address of the queried key. - -- Item: Various attributes of the identity such as stake, rank, and trust. - -- Value: The corresponding values of the attributes. - -**Example:** - -``` -btcli wallet get_identity --key <s58_address> -``` - -Note: This command is primarily used for informational purposes and has no side effects on the blockchain network state. - -**Usage**: - -```console -btcli wallets get_identity [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-k, --ss58, --coldkey_ss58, --coldkey.ss58_address, --coldkey.ss58, --key TEXT`: Coldkey address of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli stake` - -**Usage**: - -```console -btcli stake [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `add`: Stake TAO to one or more hotkeys on... -* `remove`: Unstake TAO from one or more hotkeys and... -* `list`: Display detailed stake information for a... -* `move`: Move staked TAO between hotkeys while... -* `transfer`: Transfer stake between coldkeys while... -* `swap`: Swap stake between different subnets while... -* `child`: Child Hotkey commands, alias: `children` -* `children` - -### `btcli stake add` - -Stake TAO to one or more hotkeys on specific netuids with your coldkey. - -Stake is always added through your coldkey's free balance. For stake movement, see the `btcli stake move` command. - -Common Examples: -1. Interactive staking (guided prompts): - ``` - btcli stake add - ``` - -2. Safe staking with rate tolerance of 10% with partial transaction disabled: - ``` - btcli stake add --amount 100 --netuid 1 --safe --tolerance 0.1 --no-partial - ``` - -3. Allow partial stake if rates change with tolerance of 10%: - ``` - btcli stake add --amount 300 --safe --partial --tolerance 0.1 - ``` - -4. Unsafe staking with no rate protection: - ``` - btcli stake add --amount 300 --netuid 1 --unsafe - ``` - -5. Stake to multiple hotkeys: - ``` - btcli stake add --amount 200 --include-hotkeys hk_ss58_1,hk_ss58_2,hk_ss58_3 - ``` - -6. Stake all balance to a subnet: - ``` - btcli stake add --all --netuid 3 - ``` - -Safe Staking Parameters:--safe: Enables rate tolerance checks - --tolerance: Maximum % rate change allowed (0.05 = 5%) - --partial: Complete partial stake if rates exceed tolerance - -**Usage**: - -```console -btcli stake add [OPTIONS] -``` - -**Options**: - -* `-a, --all-tokens, --all`: When set, the command stakes all the available TAO from the coldkey. -* `--amount FLOAT`: The amount of TAO to stake [default: 0.0] -* `-in, --include-hotkeys, --hotkey-ss58-address TEXT`: Specifies hotkeys by name or ss58 address to stake to. For example, `-in hk1,hk2` -* `-ex, --exclude-hotkeys TEXT`: Specifies hotkeys by name or ss58 address to not to stake to (use this option only with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` -* `--all-hotkeys / --no-all-hotkeys`: When set, this command stakes to all hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. [default: no-all-hotkeys] -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--slippage, --slippage-tolerance, --tolerance FLOAT`: Set the rate tolerance percentage for transactions (default: 0.05%). -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: Enable or disable safe staking mode (default: enabled). -* `--allow-partial-stake, --partial, --allow, --allow-partial / --no-allow-partial-stake, --no-partial, --not-allow, --not-partial`: Enable or disable partial stake mode (default: disabled). -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli stake remove` - -Unstake TAO from one or more hotkeys and transfer them back to the user's coldkey wallet. - -This command is used to withdraw TAO or Alpha stake from different hotkeys. - -Common Examples: -1. Interactive unstaking (guided prompts): - ``` - btcli stake remove - ``` - -2. Safe unstaking with 10% rate tolerance: - ``` - btcli stake remove --amount 100 --netuid 1 --safe --tolerance 0.1 - ``` - -3. Allow partial unstake if rates change: - ``` - btcli stake remove --amount 300 --safe --partial - ``` - -4. Unstake from multiple hotkeys: - ``` - btcli stake remove --amount 200 --include-hotkeys hk1,hk2,hk3 - ``` - -5. Unstake all from a hotkey: - ``` - btcli stake remove --all - ``` - -6. Unstake all Alpha from a hotkey and stake to Root: - ``` - btcli stake remove --all-alpha - ``` - -Safe Staking Parameters: - --safe: Enables rate tolerance checks during unstaking - --tolerance: Max allowed rate change (0.05 = 5%) - --partial: Complete partial unstake if rates exceed tolerance - -**Usage**: - -```console -btcli stake remove [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `-a, --amount FLOAT`: The amount of TAO to unstake. [default: 0.0] -* `--hotkey-ss58-address TEXT`: The ss58 address of the hotkey to unstake from. -* `-in, --include-hotkeys TEXT`: Specifies the hotkeys by name or ss58 address to unstake from. For example, `-in hk1,hk2` -* `-ex, --exclude-hotkeys TEXT`: Specifies the hotkeys by name or ss58 address not to unstake from (only use with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` -* `--all-hotkeys / --no-all-hotkeys`: When set, this command unstakes from all the hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. [default: no-all-hotkeys] -* `--slippage, --slippage-tolerance, --tolerance FLOAT`: Set the rate tolerance percentage for transactions (default: 0.05%). -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: Enable or disable safe staking mode (default: enabled). -* `--allow-partial-stake, --partial, --allow, --allow-partial / --no-allow-partial-stake, --no-partial, --not-allow, --not-partial`: Enable or disable partial stake mode (default: disabled). -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `-i, --interactive`: Enter interactive mode for unstaking. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli stake list` - -Display detailed stake information for a wallet across all subnets. - -Shows stake allocations, exchange rates, and emissions for each hotkey. - -Common Examples: -1. Basic stake overview: -``` -btcli stake list --wallet.name my_wallet -``` - -2. Live updating view with refresh: -``` -btcli stake list --wallet.name my_wallet --live -``` - -3. View specific coldkey by address: -``` -btcli stake list --ss58 5Dk...X3q -``` - -4. Verbose output with full values: -``` -btcli stake list --wallet.name my_wallet --verbose -``` - -**Usage**: - -```console -btcli stake list [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--ss58, --coldkey_ss58, --coldkey.ss58_address, --coldkey.ss58 TEXT`: Coldkey address of the wallet -* `--live`: Display live view of the table -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli stake move` - -Move staked TAO between hotkeys while keeping the same coldkey ownership. - -This command allows you to: -- Move stake from one hotkey to another hotkey -- Move stake between different subnets -- Keep the same coldkey ownership - -You can specify: -- The origin subnet (--origin-netuid) -- The destination subnet (--dest-netuid) -- The destination hotkey (--dest-hotkey) -- The amount to move (--amount) - -If no arguments are provided, an interactive selection menu will be shown. - -**Example:** - -``` -btcli stake move -``` - -**Usage**: - -```console -btcli stake move [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--origin-netuid INTEGER`: Origin netuid -* `--dest-netuid INTEGER`: Destination netuid -* `--dest-ss58, --dest TEXT`: Destination hotkey -* `--amount FLOAT`: The amount of TAO to stake -* `--stake-all, --all`: Stake all -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli stake transfer` - -Transfer stake between coldkeys while keeping the same hotkey ownership. - -This command allows you to: -- Transfer stake from one coldkey to another coldkey -- Keep the same hotkey ownership -- Transfer stake between different subnets - -You can specify: -- The origin subnet (--origin-netuid) -- The destination subnet (--dest-netuid) -- The destination wallet/address (--dest) -- The amount to transfer (--amount) - -If no arguments are provided, an interactive selection menu will be shown. - -**Example:** - -Transfer 100 TAO from subnet 1 to subnet 2: -``` -btcli stake transfer --origin-netuid 1 --dest-netuid 2 --dest wallet2 --amount 100 -``` - -Using SS58 address: -``` -btcli stake transfer --origin-netuid 1 --dest-netuid 2 --dest 5FrLxJsyJ5x9n2rmxFwosFraxFCKcXZDngEP9H7qjkKgHLcK --amount 100 -``` - -**Usage**: - -```console -btcli stake transfer [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--origin-netuid INTEGER`: The netuid to transfer stake from -* `--dest-netuid INTEGER`: The netuid to transfer stake to -* `--dest-ss58, --dest, --dest-coldkey TEXT`: The destination wallet name or SS58 address to transfer stake to -* `-a, --amount FLOAT`: Amount of stake to transfer -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli stake swap` - -Swap stake between different subnets while keeping the same coldkey-hotkey pair ownership. - -This command allows you to: -- Move stake from one subnet to another subnet -- Keep the same coldkey ownership -- Keep the same hotkey ownership - -You can specify: -- The origin subnet (--origin-netuid) -- The destination subnet (--dest-netuid) -- The amount to swap (--amount) - -If no arguments are provided, an interactive selection menu will be shown. - -**Example:** - -Swap 100 TAO from subnet 1 to subnet 2: -``` -btcli stake swap --wallet-name default --wallet-hotkey default --origin-netuid 1 --dest-netuid 2 --amount 100 -``` - -**Usage**: - -```console -btcli stake swap [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-o, --origin-netuid, --origin INTEGER`: The netuid to swap stake from -* `-d, --dest-netuid, --dest INTEGER`: The netuid to swap stake to -* `-a, --amount FLOAT`: Amount of stake to swap -* `--swap-all, --all`: Swap all available stake -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli stake child` - -**Usage**: - -```console -btcli stake child [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `get`: Get all the child hotkeys on a specified... -* `set`: Set child hotkeys on specified subnets. -* `revoke`: Remove all children hotkeys on a specified... -* `take`: Get and set your child hotkey take on a... - -#### `btcli stake child get` - -Get all the child hotkeys on a specified subnet. - -Users can specify the subnet and see the child hotkeys and the proportion that is given to them. This command is used to view the authority delegated to different hotkeys on the subnet. - -**Example:** - -``` -btcli stake child get --netuid 1 -``` -``` -btcli stake child get --all-netuids -``` - -**Usage**: - -```console -btcli stake child get [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet (e.g. 2) -* `--all-netuids, --all, --allnetuids`: When set, gets the child hotkeys from all the subnets. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli stake child set` - -Set child hotkeys on specified subnets. - -Users can specify the 'proportion' to delegate to child hotkeys (ss58 address). The sum of proportions cannot be greater than 1. - -This command is used to delegate authority to different hotkeys, securing their position and influence on the subnet. - -**Example:** - -``` -btcli stake child set -c 5FCL3gmjtQV4xxxxuEPEFQVhyyyyqYgNwX7drFLw7MSdBnxP -c 5Hp5dxxxxtGg7pu8dN2btyyyyVA1vELmM9dy8KQv3LxV8PA7 --hotkey default --netuid 1 -p 0.3 -p 0.7 -``` - -**Usage**: - -```console -btcli stake child set [OPTIONS] -``` - -**Options**: - -* `-c, --children TEXT`: Enter child hotkeys (ss58) -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `-p, --proportions, --prop FLOAT`: Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli stake child revoke` - -Remove all children hotkeys on a specified subnet. - -This command is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet. - -**Example:** - -``` -btcli stake child revoke --hotkey <parent_hotkey> --netuid 1 -``` - -**Usage**: - -```console -btcli stake child revoke [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 8) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli stake child take` - -Get and set your child hotkey take on a specified subnet. - -The child hotkey take must be between 0 - 18%. - -**Example:** - -To get the current take value, do not use the '--take' option: - - ``` - btcli stake child take --hotkey <child_hotkey> --netuid 1 - ``` - -To set a new take value, use the '--take' option: - - ``` - btcli stake child take --hotkey <child_hotkey> --take 0.12 --netuid 1 - ``` - -**Usage**: - -```console -btcli stake child take [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--hotkey TEXT` -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 23) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `-t, --take FLOAT`: Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli stake children` - -**Usage**: - -```console -btcli stake children [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `get`: Get all the child hotkeys on a specified... -* `set`: Set child hotkeys on specified subnets. -* `revoke`: Remove all children hotkeys on a specified... -* `take`: Get and set your child hotkey take on a... - -#### `btcli stake children get` - -Get all the child hotkeys on a specified subnet. - -Users can specify the subnet and see the child hotkeys and the proportion that is given to them. This command is used to view the authority delegated to different hotkeys on the subnet. - -**Example:** - -``` -btcli stake child get --netuid 1 -``` -``` -btcli stake child get --all-netuids -``` - -**Usage**: - -```console -btcli stake children get [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet (e.g. 2) -* `--all-netuids, --all, --allnetuids`: When set, gets the child hotkeys from all the subnets. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli stake children set` - -Set child hotkeys on specified subnets. - -Users can specify the 'proportion' to delegate to child hotkeys (ss58 address). The sum of proportions cannot be greater than 1. - -This command is used to delegate authority to different hotkeys, securing their position and influence on the subnet. - -**Example:** - -``` -btcli stake child set -c 5FCL3gmjtQV4xxxxuEPEFQVhyyyyqYgNwX7drFLw7MSdBnxP -c 5Hp5dxxxxtGg7pu8dN2btyyyyVA1vELmM9dy8KQv3LxV8PA7 --hotkey default --netuid 1 -p 0.3 -p 0.7 -``` - -**Usage**: - -```console -btcli stake children set [OPTIONS] -``` - -**Options**: - -* `-c, --children TEXT`: Enter child hotkeys (ss58) -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `-p, --proportions, --prop FLOAT`: Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli stake children revoke` - -Remove all children hotkeys on a specified subnet. - -This command is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet. - -**Example:** - -``` -btcli stake child revoke --hotkey <parent_hotkey> --netuid 1 -``` - -**Usage**: - -```console -btcli stake children revoke [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 8) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli stake children take` - -Get and set your child hotkey take on a specified subnet. - -The child hotkey take must be between 0 - 18%. - -**Example:** - -To get the current take value, do not use the '--take' option: - - ``` - btcli stake child take --hotkey <child_hotkey> --netuid 1 - ``` - -To set a new take value, use the '--take' option: - - ``` - btcli stake child take --hotkey <child_hotkey> --take 0.12 --netuid 1 - ``` - -**Usage**: - -```console -btcli stake children take [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--hotkey TEXT` -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 23) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `-t, --take FLOAT`: Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli st` - -**Usage**: - -```console -btcli st [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `add`: Stake TAO to one or more hotkeys on... -* `remove`: Unstake TAO from one or more hotkeys and... -* `list`: Display detailed stake information for a... -* `move`: Move staked TAO between hotkeys while... -* `transfer`: Transfer stake between coldkeys while... -* `swap`: Swap stake between different subnets while... -* `child`: Child Hotkey commands, alias: `children` -* `children` - -### `btcli st add` - -Stake TAO to one or more hotkeys on specific netuids with your coldkey. - -Stake is always added through your coldkey's free balance. For stake movement, see -the `btcli stake move` command. - - -Common Examples: -1. Interactive staking (guided prompts): - ``` - btcli stake add - ``` - -2. Safe staking with rate tolerance of 10% with partial transaction disabled: - ``` - btcli stake add --amount 100 --netuid 1 --safe --tolerance 0.1 --no-partial - ``` - -3. Allow partial stake if rates change with tolerance of 10%: - ``` - btcli stake add --amount 300 --safe --partial --tolerance 0.1 - ``` - -4. Unsafe staking with no rate protection: - ``` - btcli stake add --amount 300 --netuid 1 --unsafe - ``` - -5. Stake to multiple hotkeys: - ``` - btcli stake add --amount 200 --include-hotkeys hk_ss58_1,hk_ss58_2,hk_ss58_3 - ``` - -6. Stake all balance to a subnet: - ``` - btcli stake add --all --netuid 3 - ``` - -Safe Staking Parameters: --safe: Enables rate tolerance checks - --tolerance: Maximum % rate change allowed (0.05 = 5%) - --partial: Complete partial stake if rates exceed tolerance - -**Usage**: - -```console -btcli st add [OPTIONS] -``` - -**Options**: - -* `-a, --all-tokens, --all`: When set, the command stakes all the available TAO from the coldkey. -* `--amount FLOAT`: The amount of TAO to stake [default: 0.0] -* `-in, --include-hotkeys, --hotkey-ss58-address TEXT`: Specifies hotkeys by name or ss58 address to stake to. For example, `-in hk1,hk2` -* `-ex, --exclude-hotkeys TEXT`: Specifies hotkeys by name or ss58 address to not to stake to (use this option only with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` -* `--all-hotkeys / --no-all-hotkeys`: When set, this command stakes to all hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. [default: no-all-hotkeys] -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--slippage, --slippage-tolerance, --tolerance FLOAT`: Set the rate tolerance percentage for transactions (default: 0.05%). -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: Enable or disable safe staking mode (default: enabled). -* `--allow-partial-stake, --partial, --allow, --allow-partial / --no-allow-partial-stake, --no-partial, --not-allow, --not-partial`: Enable or disable partial stake mode (default: disabled). -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli st remove` - -Unstake TAO from one or more hotkeys and transfer them back to the user's coldkey wallet. - -This command is used to withdraw TAO or Alpha stake from different hotkeys. - -Common Examples: -1. Interactive unstaking (guided prompts): - ``` - btcli stake remove - ``` - -2. Safe unstaking with 10% rate tolerance: - ``` - btcli stake remove --amount 100 --netuid 1 --safe --tolerance 0.1 - ``` - -3. Allow partial unstake if rates change: - ``` - btcli stake remove --amount 300 --safe --partial - ``` - -4. Unstake from multiple hotkeys: - ``` - btcli stake remove --amount 200 --include-hotkeys hk1,hk2,hk3 - ``` - -5. Unstake all from a hotkey: - ``` - btcli stake remove --all - ``` - -6. Unstake all Alpha from a hotkey and stake to Root: - ``` - btcli stake remove --all-alpha - ``` - -Safe Staking Parameters: --safe: Enables rate tolerance checks during unstaking - --tolerance: Max allowed rate change (0.05 = 5%) - --partial: Complete partial unstake if rates exceed tolerance - -**Usage**: - -```console -btcli st remove [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `-a, --amount FLOAT`: The amount of TAO to unstake. [default: 0.0] -* `--hotkey-ss58-address TEXT`: The ss58 address of the hotkey to unstake from. -* `-in, --include-hotkeys TEXT`: Specifies the hotkeys by name or ss58 address to unstake from. For example, `-in hk1,hk2` -* `-ex, --exclude-hotkeys TEXT`: Specifies the hotkeys by name or ss58 address not to unstake from (only use with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` -* `--all-hotkeys / --no-all-hotkeys`: When set, this command unstakes from all the hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. [default: no-all-hotkeys] -* `--slippage, --slippage-tolerance, --tolerance FLOAT`: Set the rate tolerance percentage for transactions (default: 0.05%). -* `--safe-staking, --safe / --no-safe-staking, --unsafe`: Enable or disable safe staking mode (default: enabled). -* `--allow-partial-stake, --partial, --allow, --allow-partial / --no-allow-partial-stake, --no-partial, --not-allow, --not-partial`: Enable or disable partial stake mode (default: disabled). -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `-i, --interactive`: Enter interactive mode for unstaking. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli st list` - -Display detailed stake information for a wallet across all subnets. - -Shows stake allocations, exchange rates, and emissions for each hotkey. - -Common Examples: -1. Basic stake overview: -``` -btcli stake list --wallet.name my_wallet -``` - -2. Live updating view with refresh: -``` -btcli stake list --wallet.name my_wallet --live -``` - -3. View specific coldkey by address: -``` -btcli stake list --ss58 5Dk...X3q -``` - -4. Verbose output with full values: -``` -btcli stake list --wallet.name my_wallet --verbose -``` - -**Usage**: - -```console -btcli st list [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--ss58, --coldkey_ss58, --coldkey.ss58_address, --coldkey.ss58 TEXT`: Coldkey address of the wallet -* `--live`: Display live view of the table -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli st move` - -Move staked TAO between hotkeys while keeping the same coldkey ownership. - -This command allows you to: -- Move stake from one hotkey to another hotkey -- Move stake between different subnets -- Keep the same coldkey ownership - -You can specify: -- The origin subnet (--origin-netuid) -- The destination subnet (--dest-netuid) -- The destination hotkey (--dest-hotkey) -- The amount to move (--amount) - -If no arguments are provided, an interactive selection menu will be shown. - -**Example:** - -``` -btcli stake move -``` - -**Usage**: - -```console -btcli st move [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--origin-netuid INTEGER`: Origin netuid -* `--dest-netuid INTEGER`: Destination netuid -* `--dest-ss58, --dest TEXT`: Destination hotkey -* `--amount FLOAT`: The amount of TAO to stake -* `--stake-all, --all`: Stake all -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli st transfer` - -Transfer stake between coldkeys while keeping the same hotkey ownership. - -This command allows you to: -- Transfer stake from one coldkey to another coldkey -- Keep the same hotkey ownership -- Transfer stake between different subnets - -You can specify: -- The origin subnet (--origin-netuid) -- The destination subnet (--dest-netuid) -- The destination wallet/address (--dest) -- The amount to transfer (--amount) - -If no arguments are provided, an interactive selection menu will be shown. - -**Example:** - -Transfer 100 TAO from subnet 1 to subnet 2: -``` -btcli stake transfer --origin-netuid 1 --dest-netuid 2 --dest wallet2 --amount 100 -``` - -Using SS58 address: -``` -btcli stake transfer --origin-netuid 1 --dest-netuid 2 --dest 5FrLxJsyJ5x9n2rmxFwosFraxFCKcXZDngEP9H7qjkKgHLcK --amount 100 -``` - -**Usage**: - -```console -btcli st transfer [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--origin-netuid INTEGER`: The netuid to transfer stake from -* `--dest-netuid INTEGER`: The netuid to transfer stake to -* `--dest-ss58, --dest, --dest-coldkey TEXT`: The destination wallet name or SS58 address to transfer stake to -* `-a, --amount FLOAT`: Amount of stake to transfer -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli st swap` - -Swap stake between different subnets while keeping the same coldkey-hotkey pair ownership. - -This command allows you to: -- Move stake from one subnet to another subnet -- Keep the same coldkey ownership -- Keep the same hotkey ownership - -You can specify: -- The origin subnet (--origin-netuid) -- The destination subnet (--dest-netuid) -- The amount to swap (--amount) - -If no arguments are provided, an interactive selection menu will be shown. - -**Example:** - -Swap 100 TAO from subnet 1 to subnet 2: -``` -btcli stake swap --wallet-name default --wallet-hotkey default --origin-netuid 1 --dest-netuid 2 --amount 100 -``` - -**Usage**: - -```console -btcli st swap [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-o, --origin-netuid, --origin INTEGER`: The netuid to swap stake from -* `-d, --dest-netuid, --dest INTEGER`: The netuid to swap stake to -* `-a, --amount FLOAT`: Amount of stake to swap -* `--swap-all, --all`: Swap all available stake -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli st child` - -**Usage**: - -```console -btcli st child [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `get`: Get all the child hotkeys on a specified... -* `set`: Set child hotkeys on specified subnets. -* `revoke`: Remove all children hotkeys on a specified... -* `take`: Get and set your child hotkey take on a... - -#### `btcli st child get` - -Get all the child hotkeys on a specified subnet. - -Users can specify the subnet and see the child hotkeys and the proportion that is given to them. This command is used to view the authority delegated to different hotkeys on the subnet. - -**Example:** - -``` -btcli stake child get --netuid 1 -``` -``` -btcli stake child get --all-netuids -``` - -**Usage**: - -```console -btcli st child get [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet (e.g. 2) -* `--all-netuids, --all, --allnetuids`: When set, gets the child hotkeys from all the subnets. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli st child set` - -Set child hotkeys on specified subnets. - -Users can specify the 'proportion' to delegate to child hotkeys (ss58 address). The sum of proportions cannot be greater than 1. - -This command is used to delegate authority to different hotkeys, securing their position and influence on the subnet. - -**Example:** - -``` -btcli stake child set -c 5FCL3gmjtQV4xxxxuEPEFQVhyyyyqYgNwX7drFLw7MSdBnxP -c 5Hp5dxxxxtGg7pu8dN2btyyyyVA1vELmM9dy8KQv3LxV8PA7 --hotkey default --netuid 1 -p 0.3 -p 0.7 -``` - -**Usage**: - -```console -btcli st child set [OPTIONS] -``` - -**Options**: - -* `-c, --children TEXT`: Enter child hotkeys (ss58) -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `-p, --proportions, --prop FLOAT`: Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli st child revoke` - -Remove all children hotkeys on a specified subnet. - -This command is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet. - -**Example:** - -``` -btcli stake child revoke --hotkey <parent_hotkey> --netuid 1 -``` - -**Usage**: - -```console -btcli st child revoke [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 8) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli st child take` - -Get and set your child hotkey take on a specified subnet. - -The child hotkey take must be between 0 - 18%. - -**Example:** - -To get the current take value, do not use the '--take' option: - - ``` - btcli stake child take --hotkey <child_hotkey> --netuid 1 - ``` - -To set a new take value, use the '--take' option: - - ``` - btcli stake child take --hotkey <child_hotkey> --take 0.12 --netuid 1 - ``` - -**Usage**: - -```console -btcli st child take [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--hotkey TEXT` -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 23) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `-t, --take FLOAT`: Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli st children` - -**Usage**: - -```console -btcli st children [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `get`: Get all the child hotkeys on a specified... -* `set`: Set child hotkeys on specified subnets. -* `revoke`: Remove all children hotkeys on a specified... -* `take`: Get and set your child hotkey take on a... - -#### `btcli st children get` - -Get all the child hotkeys on a specified subnet. - -Users can specify the subnet and see the child hotkeys and the proportion that is given to them. This command is used to view the authority delegated to different hotkeys on the subnet. - -**Example:** - -``` -btcli stake child get --netuid 1 -``` -``` -btcli stake child get --all-netuids -``` - -**Usage**: - -```console -btcli st children get [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet (e.g. 2) -* `--all-netuids, --all, --allnetuids`: When set, gets the child hotkeys from all the subnets. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli st children set` - -Set child hotkeys on specified subnets. - -Users can specify the 'proportion' to delegate to child hotkeys (ss58 address). The sum of proportions cannot be greater than 1. - -This command is used to delegate authority to different hotkeys, securing their position and influence on the subnet. - -**Example:** - -``` -btcli stake child set -c 5FCL3gmjtQV4xxxxuEPEFQVhyyyyqYgNwX7drFLw7MSdBnxP -c 5Hp5dxxxxtGg7pu8dN2btyyyyVA1vELmM9dy8KQv3LxV8PA7 --hotkey default --netuid 1 -p 0.3 -p 0.7 -``` - -**Usage**: - -```console -btcli st children set [OPTIONS] -``` - -**Options**: - -* `-c, --children TEXT`: Enter child hotkeys (ss58) -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `-p, --proportions, --prop FLOAT`: Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli st children revoke` - -Remove all children hotkeys on a specified subnet. - -This command is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet. - -**Example:** - -``` -btcli stake child revoke --hotkey <parent_hotkey> --netuid 1 -``` - -**Usage**: - -```console -btcli st children revoke [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 8) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -#### `btcli st children take` - -Get and set your child hotkey take on a specified subnet. - -The child hotkey take must be between 0 - 18%. - -**Example:** - -To get the current take value, do not use the '--take' option: - - ``` - btcli stake child take --hotkey <child_hotkey> --netuid 1 - ``` - -To set a new take value, use the '--take' option: - - ``` - btcli stake child take --hotkey <child_hotkey> --take 0.12 --netuid 1 - ``` - -**Usage**: - -```console -btcli st children take [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--hotkey TEXT` -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 23) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `-t, --take FLOAT`: Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli sudo` - -**Usage**: - -```console -btcli sudo [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `set`: Used to set hyperparameters for a specific... -* `get`: Shows a list of the hyperparameters for... -* `senate`: Shows the Senate members of the... -* `proposals`: View active proposals for the senate in... -* `senate-vote`: Cast a vote on an active proposal in... -* `set-take`: Allows users to change their delegate take... -* `get-take`: Allows users to check their delegate take... -* `senate_vote`: Cast a vote on an active proposal in... -* `get_take`: Allows users to check their delegate take... -* `set_take`: Allows users to change their delegate take... - -### `btcli sudo set` - -Used to set hyperparameters for a specific subnet. - -This command allows subnet owners to modify hyperparameters such as its tempo, emission rates, and other hyperparameters. - -**Example:** - -``` -btcli sudo set --netuid 1 --param tempo --value 400 -``` - -**Usage**: - -```console -btcli sudo set [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--param, --parameter TEXT`: The subnet hyperparameter to set -* `--value TEXT`: Value to set the hyperparameter to. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli sudo get` - -Shows a list of the hyperparameters for the specified subnet. - -**Example:** - -``` -btcli sudo get --netuid 1 -``` - -**Usage**: - -```console -btcli sudo get [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli sudo senate` - -Shows the Senate members of the Bittensor's governance protocol. - -This command lists the delegates involved in the decision-making process of the Bittensor network, showing their names and wallet addresses. This information is crucial for understanding who holds governance roles within the network. - -**Example:** -``` -btcli sudo senate -``` - -**Usage**: - -```console -btcli sudo senate [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli sudo proposals` - -View active proposals for the senate in the Bittensor's governance protocol. - -This command displays the details of ongoing proposals, including proposal hashes, votes, thresholds, and proposal data. - -**Example:** -``` -btcli sudo proposals -``` - -**Usage**: - -```console -btcli sudo proposals [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli sudo senate-vote` - -Cast a vote on an active proposal in Bittensor's governance protocol. - -This command is used by Senate members to vote on various proposals that shape the network's future. Use `btcli sudo proposals` to see the active proposals and their hashes. - -**Usage:** -The user must specify the hash of the proposal they want to vote on. The command then allows the Senate member to cast a 'Yes' or 'No' vote, contributing to the decision-making process on the proposal. This command is crucial for Senate members to exercise their voting rights on key proposals. It plays a vital role in the governance and evolution of the Bittensor network. - -**Example:** -``` -btcli sudo senate_vote --proposal <proposal_hash> -``` - -**Usage**: - -```console -btcli sudo senate-vote [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--proposal, --proposal-hash TEXT`: The hash of the proposal to vote on. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--vote-aye / --vote-nay`: The vote casted on the proposal -* `--help`: Show this message and exit. - -### `btcli sudo set-take` - -Allows users to change their delegate take percentage. - -This command can be used to update the delegate takes. To run the command, the user must have a configured wallet with both hotkey and coldkey. -The command makes sure the new take value is within 0-18% range. - -**Example:** -``` -btcli sudo set-take --wallet-name my_wallet --wallet-hotkey my_hotkey -``` - -**Usage**: - -```console -btcli sudo set-take [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--take FLOAT`: The new take value. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli sudo get-take` - -Allows users to check their delegate take percentage. - -This command can be used to fetch the delegate take of your hotkey. - -**Example:** -``` -btcli sudo get-take --wallet-name my_wallet --wallet-hotkey my_hotkey -``` - -**Usage**: - -```console -btcli sudo get-take [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli sudo senate_vote` - -Cast a vote on an active proposal in Bittensor's governance protocol. - -This command is used by Senate members to vote on various proposals that shape the network's future. Use `btcli sudo proposals` to see the active proposals and their hashes. - -**Usage:** -The user must specify the hash of the proposal they want to vote on. The command then allows the Senate member to cast a 'Yes' or 'No' vote, contributing to the decision-making process on the proposal. This command is crucial for Senate members to exercise their voting rights on key proposals. It plays a vital role in the governance and evolution of the Bittensor network. - -**Example:** -``` -btcli sudo senate_vote --proposal <proposal_hash> -``` - -**Usage**: - -```console -btcli sudo senate_vote [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--proposal, --proposal-hash TEXT`: The hash of the proposal to vote on. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--vote-aye / --vote-nay`: The vote casted on the proposal -* `--help`: Show this message and exit. - -### `btcli sudo get_take` - -Allows users to check their delegate take percentage. - -This command can be used to fetch the delegate take of your hotkey. - -**Example:** -``` -btcli sudo get-take --wallet-name my_wallet --wallet-hotkey my_hotkey -``` - -**Usage**: - -```console -btcli sudo get_take [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli sudo set_take` - -Allows users to change their delegate take percentage. - -This command can be used to update the delegate takes. To run the command, the user must have a configured wallet with both hotkey and coldkey. -The command makes sure the new take value is within 0-18% range. - -**Example:** -``` -btcli sudo set-take --wallet-name my_wallet --wallet-hotkey my_hotkey -``` - -**Usage**: - -```console -btcli sudo set_take [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--take FLOAT`: The new take value. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli su` - -**Usage**: - -```console -btcli su [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `set`: Used to set hyperparameters for a specific... -* `get`: Shows a list of the hyperparameters for... -* `senate`: Shows the Senate members of the... -* `proposals`: View active proposals for the senate in... -* `senate-vote`: Cast a vote on an active proposal in... -* `set-take`: Allows users to change their delegate take... -* `get-take`: Allows users to check their delegate take... -* `senate_vote`: Cast a vote on an active proposal in... -* `get_take`: Allows users to check their delegate take... -* `set_take`: Allows users to change their delegate take... - -### `btcli su set` - -Used to set hyperparameters for a specific subnet. - -This command allows subnet owners to modify hyperparameters such as its tempo, emission rates, and other hyperparameters. - -**Example:** - -``` -btcli sudo set --netuid 1 --param tempo --value 400 -``` - -**Usage**: - -```console -btcli su set [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--param, --parameter TEXT`: The subnet hyperparameter to set -* `--value TEXT`: Value to set the hyperparameter to. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli su get` - -Shows a list of the hyperparameters for the specified subnet. - -**Example:** - -``` -btcli sudo get --netuid 1 -``` - -**Usage**: - -```console -btcli su get [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli su senate` - -Shows the Senate members of the Bittensor's governance protocol. - -This command lists the delegates involved in the decision-making process of the Bittensor network, showing their names and wallet addresses. This information is crucial for understanding who holds governance roles within the network. - -**Example:** -``` -btcli sudo senate -``` - -**Usage**: - -```console -btcli su senate [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli su proposals` - -View active proposals for the senate in the Bittensor's governance protocol. - -This command displays the details of ongoing proposals, including proposal hashes, votes, thresholds, and proposal data. - -**Example:** -``` -btcli sudo proposals -``` - -**Usage**: - -```console -btcli su proposals [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli su senate-vote` - -Cast a vote on an active proposal in Bittensor's governance protocol. - -This command is used by Senate members to vote on various proposals that shape the network's future. Use `btcli sudo proposals` to see the active proposals and their hashes. - -**Usage:** -The user must specify the hash of the proposal they want to vote on. The command then allows the Senate member to cast a 'Yes' or 'No' vote, contributing to the decision-making process on the proposal. This command is crucial for Senate members to exercise their voting rights on key proposals. It plays a vital role in the governance and evolution of the Bittensor network. - -**Example:** -``` -btcli sudo senate_vote --proposal <proposal_hash> -``` - -**Usage**: - -```console -btcli su senate-vote [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--proposal, --proposal-hash TEXT`: The hash of the proposal to vote on. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--vote-aye / --vote-nay`: The vote casted on the proposal -* `--help`: Show this message and exit. - -### `btcli su set-take` - -Allows users to change their delegate take percentage. - -This command can be used to update the delegate takes. To run the command, the user must have a configured wallet with both hotkey and coldkey. -The command makes sure the new take value is within 0-18% range. - -**Example:** -``` -btcli sudo set-take --wallet-name my_wallet --wallet-hotkey my_hotkey -``` - -**Usage**: - -```console -btcli su set-take [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--take FLOAT`: The new take value. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli su get-take` - -Allows users to check their delegate take percentage. - -This command can be used to fetch the delegate take of your hotkey. - -**Example:** -``` -btcli sudo get-take --wallet-name my_wallet --wallet-hotkey my_hotkey -``` - -**Usage**: - -```console -btcli su get-take [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli su senate_vote` - -Cast a vote on an active proposal in Bittensor's governance protocol. - -This command is used by Senate members to vote on various proposals that shape the network's future. Use `btcli sudo proposals` to see the active proposals and their hashes. - -**Usage:** -The user must specify the hash of the proposal they want to vote on. The command then allows the Senate member to cast a 'Yes' or 'No' vote, contributing to the decision-making process on the proposal. This command is crucial for Senate members to exercise their voting rights on key proposals. It plays a vital role in the governance and evolution of the Bittensor network. - -**Example:** -``` -btcli sudo senate_vote --proposal <proposal_hash> -``` - -**Usage**: - -```console -btcli su senate_vote [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--proposal, --proposal-hash TEXT`: The hash of the proposal to vote on. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--vote-aye / --vote-nay`: The vote casted on the proposal -* `--help`: Show this message and exit. - -### `btcli su get_take` - -Allows users to check their delegate take percentage. - -This command can be used to fetch the delegate take of your hotkey. - -**Example:** -``` -btcli sudo get-take --wallet-name my_wallet --wallet-hotkey my_hotkey -``` - -**Usage**: - -```console -btcli su get_take [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli su set_take` - -Allows users to change their delegate take percentage. - -This command can be used to update the delegate takes. To run the command, the user must have a configured wallet with both hotkey and coldkey. -The command makes sure the new take value is within 0-18% range. - -**Example:** -``` -btcli sudo set-take --wallet-name my_wallet --wallet-hotkey my_hotkey -``` - -**Usage**: - -```console -btcli su set_take [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--take FLOAT`: The new take value. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli subnets` - -**Usage**: - -```console -btcli subnets [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `hyperparameters`: Shows a list of the hyperparameters for... -* `list`: List all subnets and their detailed... -* `burn-cost`: Shows the required amount of TAO to be... -* `create`: Registers a new subnet on the network. -* `pow-register`: Register a neuron (a subnet validator or a... -* `register`: Register a neuron (a subnet validator or a... -* `metagraph`: Displays detailed information about a... -* `show`: Displays detailed information about a... -* `price`: Shows the historical price of a subnet for... -* `burn_cost`: Shows the required amount of TAO to be... -* `pow_register`: Register a neuron (a subnet validator or a... - -### `btcli subnets hyperparameters` - -Shows a list of the hyperparameters for the specified subnet. - -**Example:** - -``` -btcli sudo get --netuid 1 -``` - -**Usage**: - -```console -btcli subnets hyperparameters [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnets list` - -List all subnets and their detailed information. - - Common Examples: - 1. List all subnets: - ``` - btcli subnets list - ``` - - 2. List all subnets in live mode: - ``` - btcli subnets list --live - ``` - -Output Columns: Netuid - Subnet identifier number - Name - Subnet name with currency symbol (τ/α/β etc) - Price (τ_in/α_in) - Exchange rate (TAO per alpha token) - Market Cap (α * Price) - Total value in TAO (alpha tokens × price) - Emission (τ) - TAO rewards emitted per block to subnet - P (τ_in, α_in) - Pool reserves (Tao reserves, alpha reserves) in liquidity pool - Stake (α_out) - Total staked alpha tokens across all hotkeys (alpha outstanding) - Supply (α) - Circulating alpha token supply - Tempo (k/n) - Block interval for subnet updates - - **Example:** - - ``` - btcli subnets list - ``` - -**Usage**: - -```console -btcli subnets list [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--live`: Display live view of the table -* `--help`: Show this message and exit. - -### `btcli subnets burn-cost` - -Shows the required amount of TAO to be recycled for creating a new subnet, i.e., cost of registering a new subnet. - -The current implementation anneals the cost of creating a subnet over a period of two days. If the displayed cost is unappealing to you, check back in a day or two to see if it has decreased to a more affordable level. - -**Example:** - -``` -btcli subnets burn_cost -``` - -**Usage**: - -```console -btcli subnets burn-cost [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnets create` - -Registers a new subnet on the network. - -This command allows you to create a new subnet and set the subnet's identity. -You also have the option to set your own identity after the registration is complete. - -Common Examples: -1. Interactive subnet creation: -``` -btcli subnets create -``` - -2. Create with GitHub repo and contact email: - -``` -btcli subnets create --subnet-name MySubnet --github-repo https://github.com/myorg/mysubnet --subnet-contact team@mysubnet.net -``` -**Usage**: - -```console -btcli subnets create [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--subnet-name, --name TEXT`: Name of the subnet -* `--github-repo, --repo TEXT`: GitHub repository URL -* `--subnet-contact, --contact, --email TEXT`: Contact email for subnet -* `--subnet-url, --url TEXT`: Subnet URL -* `--discord-handle, --discord TEXT`: Discord handle -* `--description TEXT`: Description -* `--additional-info TEXT`: Additional information -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnets pow-register` - -Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW). - -This method is an alternative registration process that uses computational work for securing a neuron's place on the subnet. - -The command starts by verifying the existence of the specified subnet. If the subnet does not exist, it terminates with an error message. On successful verification, the POW registration process is initiated, which requires solving computational puzzles. - -The command also supports additional wallet and subtensor arguments, enabling further customization of the registration process. - -**Example:** - -``` -btcli pow_register --netuid 1 --num_processes 4 --cuda -``` - -Note: This command is suitable for users with adequate computational resources to participate in POW registration. -It requires a sound understanding of the network's operations and POW mechanics. Users should ensure their systems meet the necessary hardware and software requirements, particularly when opting for CUDA-based GPU acceleration. - -This command may be disabled by the subnet owner. For example, on netuid 1 this is permanently disabled. - -**Usage**: - -```console -btcli subnets pow-register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--processors INTEGER`: Number of processors to use for POW registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for the next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set the flag to use CUDA for POW registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s), in the order of the device speed (0 is the fastest). [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--help`: Show this message and exit. - -### `btcli subnets register` - -Register a neuron (a subnet validator or a subnet miner) in the specified subnet by recycling some TAO. - -Before registering, the command checks if the specified subnet exists and whether the user's balance is sufficient to cover the registration cost. - -The registration cost is determined by the current recycle amount for the specified subnet. If the balance is insufficient or the subnet does not exist, the command will exit with an error message. - -**Example:** - -``` -btcli subnets register --netuid 1 -``` - -**Usage**: - -```console -btcli subnets register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnets metagraph` - -Displays detailed information about a subnet including participants and their state. - -**Example:** - -``` -btcli subnets list -``` - -**Usage**: - -```console -btcli subnets metagraph [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli subnets show` - -Displays detailed information about a subnet including participants and their state. - -**Example:** - -``` -btcli subnets list -``` - -**Usage**: - -```console -btcli subnets show [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli subnets price` - -Shows the historical price of a subnet for the past 24 hours. - -This command displays the historical price of a subnet for the past 24 hours. -If the `--all` flag is used, the command will display the price for all subnets in html format. -If the `--html` flag is used, the command will display the price in an HTML chart. -If the `--log-scale` flag is used, the command will display the price in log scale. -If no html flag is used, the command will display the price in the cli. - -**Example:** - -``` -btcli subnets price --netuid 1 -``` -``` -btcli subnets price --netuid 1 --html --log -``` -``` -btcli subnets price --all --html -``` -``` -btcli subnets price --netuids 1,2,3,4 --html -``` - -**Usage**: - -```console -btcli subnets price [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `-n, --netuids, --netuid TEXT`: Netuid(s) to show the price for. -* `--interval-hours, --interval INTEGER`: The number of hours to show the historical price for. [default: 24] -* `--all-netuids, --all`: Show the price for all subnets. -* `--log-scale, --log`: Show the price in log scale. -* `--html`: Display the table as HTML in the browser. -* `--help`: Show this message and exit. - -### `btcli subnets burn_cost` - -Shows the required amount of TAO to be recycled for creating a new subnet, i.e., cost of registering a new subnet. - -The current implementation anneals the cost of creating a subnet over a period of two days. If the displayed cost is unappealing to you, check back in a day or two to see if it has decreased to a more affordable level. - -**Example:** - -``` -btcli subnets burn_cost -``` - -**Usage**: - -```console -btcli subnets burn_cost [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnets pow_register` - -Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW). - -This method is an alternative registration process that uses computational work for securing a neuron's place on the subnet. - -The command starts by verifying the existence of the specified subnet. If the subnet does not exist, it terminates with an error message. On successful verification, the POW registration process is initiated, which requires solving computational puzzles. - -The command also supports additional wallet and subtensor arguments, enabling further customization of the registration process. - -**Example:** - -``` -btcli pow_register --netuid 1 --num_processes 4 --cuda -``` - -Note: This command is suitable for users with adequate computational resources to participate in POW registration. -It requires a sound understanding of the network's operations and POW mechanics. Users should ensure their systems meet the necessary hardware and software requirements, particularly when opting for CUDA-based GPU acceleration. - -This command may be disabled by the subnet owner. For example, on netuid 1 this is permanently disabled. - -**Usage**: - -```console -btcli subnets pow_register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--processors INTEGER`: Number of processors to use for POW registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for the next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set the flag to use CUDA for POW registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s), in the order of the device speed (0 is the fastest). [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--help`: Show this message and exit. - -## `btcli s` - -**Usage**: - -```console -btcli s [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `hyperparameters`: Shows a list of the hyperparameters for... -* `list`: List all subnets and their detailed... -* `burn-cost`: Shows the required amount of TAO to be... -* `create`: Registers a new subnet on the network. -* `pow-register`: Register a neuron (a subnet validator or a... -* `register`: Register a neuron (a subnet validator or a... -* `metagraph`: Displays detailed information about a... -* `show`: Displays detailed information about a... -* `price`: Shows the historical price of a subnet for... -* `burn_cost`: Shows the required amount of TAO to be... -* `pow_register`: Register a neuron (a subnet validator or a... - -### `btcli s hyperparameters` - -Shows a list of the hyperparameters for the specified subnet. - -**Example:** - -``` -btcli sudo get --netuid 1 -``` - -**Usage**: - -```console -btcli s hyperparameters [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli s list` - -List all subnets and their detailed information. - - Common Examples: - 1. List all subnets: - ``` - btcli subnets list - ``` - - 2. List all subnets in live mode: - ``` - btcli subnets list --live - ``` - -Output Columns: Netuid - Subnet identifier number - Name - Subnet name with currency symbol (τ/α/β etc) - Price (τ_in/α_in) - Exchange rate (TAO per alpha token) - Market Cap (α * Price) - Total value in TAO (alpha tokens × price) - Emission (τ) - TAO rewards emitted per block to subnet - P (τ_in, α_in) - Pool reserves (Tao reserves, alpha reserves) in liquidity pool - Stake (α_out) - Total staked alpha tokens across all hotkeys (alpha outstanding) - Supply (α) - Circulating alpha token supply - Tempo (k/n) - Block interval for subnet updates - - **Example:** - - ``` - btcli subnets list - ``` - -**Usage**: - -```console -btcli s list [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--live`: Display live view of the table -* `--help`: Show this message and exit. - -### `btcli s burn-cost` - -Shows the required amount of TAO to be recycled for creating a new subnet, i.e., cost of registering a new subnet. - -The current implementation anneals the cost of creating a subnet over a period of two days. If the displayed cost is unappealing to you, check back in a day or two to see if it has decreased to a more affordable level. - -**Example:** - -``` -btcli subnets burn_cost -``` - -**Usage**: - -```console -btcli s burn-cost [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli s create` - -Registers a new subnet on the network. - -This command allows you to create a new subnet and set the subnet's identity. -You also have the option to set your own identity after the registration is complete. - -Common Examples: -1. Interactive subnet creation: -``` -btcli subnets create -``` - -2. Create with GitHub repo and contact email: - -``` -btcli subnets create --subnet-name MySubnet --github-repo https://github.com/myorg/mysubnet --subnet-contact team@mysubnet.net -``` - -**Usage**: - -```console -btcli s create [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--subnet-name, --name TEXT`: Name of the subnet -* `--github-repo, --repo TEXT`: GitHub repository URL -* `--subnet-contact, --contact, --email TEXT`: Contact email for subnet -* `--subnet-url, --url TEXT`: Subnet URL -* `--discord-handle, --discord TEXT`: Discord handle -* `--description TEXT`: Description -* `--additional-info TEXT`: Additional information -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli s pow-register` - -Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW). - -This method is an alternative registration process that uses computational work for securing a neuron's place on the subnet. - -The command starts by verifying the existence of the specified subnet. If the subnet does not exist, it terminates with an error message. On successful verification, the POW registration process is initiated, which requires solving computational puzzles. - -The command also supports additional wallet and subtensor arguments, enabling further customization of the registration process. - -**Example:** - -``` -btcli pow_register --netuid 1 --num_processes 4 --cuda -``` - -Note: This command is suitable for users with adequate computational resources to participate in POW registration. -It requires a sound understanding of the network's operations and POW mechanics. Users should ensure their systems meet the necessary hardware and software requirements, particularly when opting for CUDA-based GPU acceleration. - -This command may be disabled by the subnet owner. For example, on netuid 1 this is permanently disabled. - -**Usage**: - -```console -btcli s pow-register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--processors INTEGER`: Number of processors to use for POW registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for the next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set the flag to use CUDA for POW registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s), in the order of the device speed (0 is the fastest). [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--help`: Show this message and exit. - -### `btcli s register` - -Register a neuron (a subnet validator or a subnet miner) in the specified subnet by recycling some TAO. - -Before registering, the command checks if the specified subnet exists and whether the user's balance is sufficient to cover the registration cost. - -The registration cost is determined by the current recycle amount for the specified subnet. If the balance is insufficient or the subnet does not exist, the command will exit with an error message. - -**Example:** - -``` -btcli subnets register --netuid 1 -``` - -**Usage**: - -```console -btcli s register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli s metagraph` - -Displays detailed information about a subnet including participants and their state. - -**Example:** - -``` -btcli subnets list -``` - -**Usage**: - -```console -btcli s metagraph [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli s show` - -Displays detailed information about a subnet including participants and their state. - -**Example:** - -``` -btcli subnets list -``` - -**Usage**: - -```console -btcli s show [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli s price` - -Shows the historical price of a subnet for the past 24 hours. - -This command displays the historical price of a subnet for the past 24 hours. -If the `--all` flag is used, the command will display the price for all subnets in html format. -If the `--html` flag is used, the command will display the price in an HTML chart. -If the `--log-scale` flag is used, the command will display the price in log scale. -If no html flag is used, the command will display the price in the cli. - -**Example:** - -``` -btcli subnets price --netuid 1 -``` -``` -btcli subnets price --netuid 1 --html --log -``` -``` -btcli subnets price --all --html -``` -``` -btcli subnets price --netuids 1,2,3,4 --html -``` - -**Usage**: - -```console -btcli s price [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `-n, --netuids, --netuid TEXT`: Netuid(s) to show the price for. -* `--interval-hours, --interval INTEGER`: The number of hours to show the historical price for. [default: 24] -* `--all-netuids, --all`: Show the price for all subnets. -* `--log-scale, --log`: Show the price in log scale. -* `--html`: Display the table as HTML in the browser. -* `--help`: Show this message and exit. - -### `btcli s burn_cost` - -Shows the required amount of TAO to be recycled for creating a new subnet, i.e., cost of registering a new subnet. - -The current implementation anneals the cost of creating a subnet over a period of two days. If the displayed cost is unappealing to you, check back in a day or two to see if it has decreased to a more affordable level. - -**Example:** - -``` -btcli subnets burn_cost -``` - -**Usage**: - -```console -btcli s burn_cost [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli s pow_register` - -Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW). - -This method is an alternative registration process that uses computational work for securing a neuron's place on the subnet. - -The command starts by verifying the existence of the specified subnet. If the subnet does not exist, it terminates with an error message. On successful verification, the POW registration process is initiated, which requires solving computational puzzles. - -The command also supports additional wallet and subtensor arguments, enabling further customization of the registration process. - -**Example:** - -``` -btcli pow_register --netuid 1 --num_processes 4 --cuda -``` - -Note: This command is suitable for users with adequate computational resources to participate in POW registration. -It requires a sound understanding of the network's operations and POW mechanics. Users should ensure their systems meet the necessary hardware and software requirements, particularly when opting for CUDA-based GPU acceleration. - -This command may be disabled by the subnet owner. For example, on netuid 1 this is permanently disabled. - -**Usage**: - -```console -btcli s pow_register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--processors INTEGER`: Number of processors to use for POW registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for the next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set the flag to use CUDA for POW registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s), in the order of the device speed (0 is the fastest). [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--help`: Show this message and exit. - -## `btcli subnet` - -**Usage**: - -```console -btcli subnet [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `hyperparameters`: Shows a list of the hyperparameters for... -* `list`: List all subnets and their detailed... -* `burn-cost`: Shows the required amount of TAO to be... -* `create`: Registers a new subnet on the network. -* `pow-register`: Register a neuron (a subnet validator or a... -* `register`: Register a neuron (a subnet validator or a... -* `metagraph`: Displays detailed information about a... -* `show`: Displays detailed information about a... -* `price`: Shows the historical price of a subnet for... -* `burn_cost`: Shows the required amount of TAO to be... -* `pow_register`: Register a neuron (a subnet validator or a... - -### `btcli subnet hyperparameters` - -Shows a list of the hyperparameters for the specified subnet. - -**Example:** - -``` -btcli sudo get --netuid 1 -``` - -**Usage**: - -```console -btcli subnet hyperparameters [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnet list` - -List all subnets and their detailed information. - - Common Examples: - 1. List all subnets: - ``` - btcli subnets list - ``` - - 2. List all subnets in live mode: - ``` - btcli subnets list --live - ``` - -Output Columns: Netuid - Subnet identifier number - Name - Subnet name with currency symbol (τ/α/β etc) - Price (τ_in/α_in) - Exchange rate (TAO per alpha token) - Market Cap (α * Price) - Total value in TAO (alpha tokens × price) - Emission (τ) - TAO rewards emitted per block to subnet - P (τ_in, α_in) - Pool reserves (Tao reserves, alpha reserves) in liquidity pool - Stake (α_out) - Total staked alpha tokens across all hotkeys (alpha outstanding) - Supply (α) - Circulating alpha token supply - Tempo (k/n) - Block interval for subnet updates - - **Example:** - - ``` - btcli subnets list - ``` - -**Usage**: - -```console -btcli subnet list [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--live`: Display live view of the table -* `--help`: Show this message and exit. - -### `btcli subnet burn-cost` - -Shows the required amount of TAO to be recycled for creating a new subnet, i.e., cost of registering a new subnet. - -The current implementation anneals the cost of creating a subnet over a period of two days. If the displayed cost is unappealing to you, check back in a day or two to see if it has decreased to a more affordable level. - -**Example:** - -``` -btcli subnets burn_cost -``` - -**Usage**: - -```console -btcli subnet burn-cost [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnet create` - -Registers a new subnet on the network. - -This command allows you to create a new subnet and set the subnet's identity. -You also have the option to set your own identity after the registration is complete. - -Common Examples: -1. Interactive subnet creation: -``` -btcli subnets create -``` - -2. Create with GitHub repo and contact email: - -``` -btcli subnets create --subnet-name MySubnet --github-repo https://github.com/myorg/mysubnet --subnet-contact team@mysubnet.net -``` - -**Usage**: - -```console -btcli subnet create [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--subnet-name, --name TEXT`: Name of the subnet -* `--github-repo, --repo TEXT`: GitHub repository URL -* `--subnet-contact, --contact, --email TEXT`: Contact email for subnet -* `--subnet-url, --url TEXT`: Subnet URL -* `--discord-handle, --discord TEXT`: Discord handle -* `--description TEXT`: Description -* `--additional-info TEXT`: Additional information -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnet pow-register` - -Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW). - -This method is an alternative registration process that uses computational work for securing a neuron's place on the subnet. - -The command starts by verifying the existence of the specified subnet. If the subnet does not exist, it terminates with an error message. On successful verification, the POW registration process is initiated, which requires solving computational puzzles. - -The command also supports additional wallet and subtensor arguments, enabling further customization of the registration process. - -**Example:** - -``` -btcli pow_register --netuid 1 --num_processes 4 --cuda -``` - -Note: This command is suitable for users with adequate computational resources to participate in POW registration. -It requires a sound understanding of the network's operations and POW mechanics. Users should ensure their systems meet the necessary hardware and software requirements, particularly when opting for CUDA-based GPU acceleration. - -This command may be disabled by the subnet owner. For example, on netuid 1 this is permanently disabled. - -**Usage**: - -```console -btcli subnet pow-register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--processors INTEGER`: Number of processors to use for POW registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for the next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set the flag to use CUDA for POW registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s), in the order of the device speed (0 is the fastest). [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--help`: Show this message and exit. - -### `btcli subnet register` - -Register a neuron (a subnet validator or a subnet miner) in the specified subnet by recycling some TAO. - -Before registering, the command checks if the specified subnet exists and whether the user's balance is sufficient to cover the registration cost. - -The registration cost is determined by the current recycle amount for the specified subnet. If the balance is insufficient or the subnet does not exist, the command will exit with an error message. - -**Example:** - -``` -btcli subnets register --netuid 1 -``` - -**Usage**: - -```console -btcli subnet register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnet metagraph` - -Displays detailed information about a subnet including participants and their state. - -**Example:** - -``` -btcli subnets list -``` - -**Usage**: - -```console -btcli subnet metagraph [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli subnet show` - -Displays detailed information about a subnet including participants and their state. - -**Example:** - -``` -btcli subnets list -``` - -**Usage**: - -```console -btcli subnet show [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. - -### `btcli subnet price` - -Shows the historical price of a subnet for the past 24 hours. - -This command displays the historical price of a subnet for the past 24 hours. -If the `--all` flag is used, the command will display the price for all subnets in html format. -If the `--html` flag is used, the command will display the price in an HTML chart. -If the `--log-scale` flag is used, the command will display the price in log scale. -If no html flag is used, the command will display the price in the cli. - -**Example:** - -``` -btcli subnets price --netuid 1 -``` -``` -btcli subnets price --netuid 1 --html --log -``` -``` -btcli subnets price --all --html -``` -``` -btcli subnets price --netuids 1,2,3,4 --html -``` - -**Usage**: - -```console -btcli subnet price [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `-n, --netuids, --netuid TEXT`: Netuid(s) to show the price for. -* `--interval-hours, --interval INTEGER`: The number of hours to show the historical price for. [default: 24] -* `--all-netuids, --all`: Show the price for all subnets. -* `--log-scale, --log`: Show the price in log scale. -* `--html`: Display the table as HTML in the browser. -* `--help`: Show this message and exit. - -### `btcli subnet burn_cost` - -Shows the required amount of TAO to be recycled for creating a new subnet, i.e., cost of registering a new subnet. - -The current implementation anneals the cost of creating a subnet over a period of two days. If the displayed cost is unappealing to you, check back in a day or two to see if it has decreased to a more affordable level. - -**Example:** - -``` -btcli subnets burn_cost -``` - -**Usage**: - -```console -btcli subnet burn_cost [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli subnet pow_register` - -Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW). - -This method is an alternative registration process that uses computational work for securing a neuron's place on the subnet. - -The command starts by verifying the existence of the specified subnet. If the subnet does not exist, it terminates with an error message. On successful verification, the POW registration process is initiated, which requires solving computational puzzles. - -The command also supports additional wallet and subtensor arguments, enabling further customization of the registration process. - -**Example:** - -``` -btcli pow_register --netuid 1 --num_processes 4 --cuda -``` - -Note: This command is suitable for users with adequate computational resources to participate in POW registration. -It requires a sound understanding of the network's operations and POW mechanics. Users should ensure their systems meet the necessary hardware and software requirements, particularly when opting for CUDA-based GPU acceleration. - -This command may be disabled by the subnet owner. For example, on netuid 1 this is permanently disabled. - -**Usage**: - -```console -btcli subnet pow_register [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `--processors INTEGER`: Number of processors to use for POW registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for the next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set the flag to use CUDA for POW registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s), in the order of the device speed (0 is the fastest). [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--help`: Show this message and exit. - -## `btcli weights` - -**Usage**: - -```console -btcli weights [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `reveal`: Reveal weights for a specific subnet. -* `commit`: Commit weights for specific subnet. - -### `btcli weights reveal` - -Reveal weights for a specific subnet. - -You must specify the netuid, the UIDs you are interested in, and weights you wish to reveal. - -**Example:** - -``` -btcli wt reveal --netuid 1 --uids 1,2,3,4 --weights 0.1,0.2,0.3,0.4 --salt 163,241,217,11,161,142,147,189 -``` - -**Usage**: - -```console -btcli weights reveal [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `-u, --uids TEXT`: Corresponding UIDs for the specified netuid, e.g. -u 1,2,3 ... -* `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. -* `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163,241,217 ... -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli weights commit` - -Commit weights for specific subnet. - -Use this command to commit weights for a specific subnet. You must specify the netuid, the UIDs you are interested in, and the weights you wish to commit. - -**Example:** - -``` -btcli wt commit --netuid 1 --uids 1,2,3,4 --w 0.1,0.2,0.3 -``` - -Note: This command is used to commit weights for a specific subnet and requires the user to have the necessary -permissions. - -**Usage**: - -```console -btcli weights commit [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `-u, --uids TEXT`: UIDs of interest for the specified netuid, e.g. -u 1,2,3 ... -* `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. -* `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163 -s 241 -s 217 ... -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli wt` - -**Usage**: - -```console -btcli wt [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `reveal`: Reveal weights for a specific subnet. -* `commit`: Commit weights for specific subnet. - -### `btcli wt reveal` - -Reveal weights for a specific subnet. - -You must specify the netuid, the UIDs you are interested in, and weights you wish to reveal. - -**Example:** - -``` -btcli wt reveal --netuid 1 --uids 1,2,3,4 --weights 0.1,0.2,0.3,0.4 --salt 163,241,217,11,161,142,147,189 -``` - -**Usage**: - -```console -btcli wt reveal [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `-u, --uids TEXT`: Corresponding UIDs for the specified netuid, e.g. -u 1,2,3 ... -* `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. -* `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163,241,217 ... -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli wt commit` - -Commit weights for specific subnet. - -Use this command to commit weights for a specific subnet. You must specify the netuid, the UIDs you are interested in, and the weights you wish to commit. - -**Example:** - -``` -btcli wt commit --netuid 1 --uids 1,2,3,4 --w 0.1,0.2,0.3 -``` - -Note: This command is used to commit weights for a specific subnet and requires the user to have the necessary -permissions. - -**Usage**: - -```console -btcli wt commit [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `-u, --uids TEXT`: UIDs of interest for the specified netuid, e.g. -u 1,2,3 ... -* `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. -* `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163 -s 241 -s 217 ... -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli weight` - -**Usage**: - -```console -btcli weight [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `reveal`: Reveal weights for a specific subnet. -* `commit`: Commit weights for specific subnet. - -### `btcli weight reveal` - -Reveal weights for a specific subnet. - -You must specify the netuid, the UIDs you are interested in, and weights you wish to reveal. - -**Example:** - -``` -btcli wt reveal --netuid 1 --uids 1,2,3,4 --weights 0.1,0.2,0.3,0.4 --salt 163,241,217,11,161,142,147,189 -``` - -**Usage**: - -```console -btcli weight reveal [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `-u, --uids TEXT`: Corresponding UIDs for the specified netuid, e.g. -u 1,2,3 ... -* `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. -* `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163,241,217 ... -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### `btcli weight commit` - -Commit weights for specific subnet. - -Use this command to commit weights for a specific subnet. You must specify the netuid, the UIDs you are interested in, and the weights you wish to commit. - -**Example:** - -``` -btcli wt commit --netuid 1 --uids 1,2,3,4 --w 0.1,0.2,0.3 -``` - -Note: This command is used to commit weights for a specific subnet and requires the user to have the necessary -permissions. - -**Usage**: - -```console -btcli weight commit [OPTIONS] -``` - -**Options**: - -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the network, (e.g. 1). -* `-u, --uids TEXT`: UIDs of interest for the specified netuid, e.g. -u 1,2,3 ... -* `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. -* `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163 -s 241 -s 217 ... -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -## `btcli utils` - -**Usage**: - -```console -btcli utils [OPTIONS] COMMAND [ARGS]... -``` - -**Options**: - -* `--help`: Show this message and exit. - -**Commands**: - -* `convert`: Allows for converting between tao and rao... - -### `btcli utils convert` - -Allows for converting between tao and rao using the specified flags - -**Usage**: - -```console -btcli utils convert [OPTIONS] -``` - -**Options**: - -* `--rao TEXT`: Convert amount from Rao -* `--tao FLOAT`: Convert amount from Tao -* `--help`: Show this message and exit. ---- -Made with :heart: by The Openτensor Foundaτion \ No newline at end of file diff --git a/docs/btcli-permissions.md b/docs/btcli/btcli-permissions.md similarity index 85% rename from docs/btcli-permissions.md rename to docs/btcli/btcli-permissions.md index 65aa684863..456b4e8261 100644 --- a/docs/btcli-permissions.md +++ b/docs/btcli/btcli-permissions.md @@ -8,16 +8,16 @@ This page details the requirements for all of the `btcli` commands. See also the `btcli` permissions guides for specific Bittensor personas: -- [Staker's Guide to `BTCLI`](./staking-and-delegation/stakers-btcli-guide) -- [Miner's Guide to `BTCLI`](./miners/miners-btcli-guide) -- [Validator's Guide to `BTCLI`](./validators/validators-btcli-guide) -- [Subnet Creator's Guide to `BTCLI`](./subnets/subnet-creators-btcli-guide) -- [Senator's Guide to `BTCLI`](./governance/senators-btcli-guide) +- [Staker's Guide to `BTCLI`](../staking-and-delegation/stakers-btcli-guide) +- [Miner's Guide to `BTCLI`](../miners/miners-btcli-guide) +- [Validator's Guide to `BTCLI`](../validators/validators-btcli-guide) +- [Subnet Creator's Guide to `BTCLI`](../subnets/subnet-creators-btcli-guide) +- [Senator's Guide to `BTCLI`](../governance/senators-btcli-guide) Other resources: -- [Introduction to Wallets, Coldkeys and Hotkeys in Bittensor](./getting-started/wallets) -- [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey-security) +- [Introduction to Wallets, Coldkeys and Hotkeys in Bittensor](../keys/wallets) +- [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security) ## Bittensor work environments and security requirements @@ -25,32 +25,34 @@ Interacting with Bittensor generally falls into one of three levels of security, The workstations you use to do this work can be referred to as a permissionless workstation (requiring neither private key), a coldkey workstation or a hotkey workstation, depending on which private key is provisioned. -1. A **permissionless workstation** has only coldkey *public keys* on it. Public keys are sufficient for viewing all information about a wallet, such as TAO and alpha stake balances. Information about wallets, subnets, miners, and validators can and should be viewed without initializing your private keys on a device, to avoid the security risk of compromising your keys. +1. A **permissionless workstation** has only coldkey _public keys_ on it. Public keys are sufficient for viewing all information about a wallet, such as TAO and alpha stake balances. Information about wallets, subnets, miners, and validators can and should be viewed without initializing your private keys on a device, to avoid the security risk of compromising your keys. - :::tip coldkey workstation security - See [Permissionless workstation](./getting-started/coldkey-hotkey-security#permissionless-workstation) - ::: + :::tip coldkey workstation security + See [Permissionless workstation](../keys/coldkey-hotkey-security#permissionless-workstation) + ::: -1. A **coldkey workstation** contains one or more coldkey private key in the `wallet_path`. For any coldkey associated with mainnet TAO, the coldkey workstation should be held to the highest possible security standards. +1. A **coldkey workstation** contains one or more coldkey private key in the `wallet_path`. For any coldkey associated with mainnet TAO, the coldkey workstation should be held to the highest possible security standards. - :::tip coldkey workstation security - See [Coldkey workstation](./ getting-started/coldkey-hotkey-security#coldkey-workstation) - ::: + :::tip coldkey workstation security + See [Coldkey workstation](../keys/coldkey-hotkey-security#coldkey-workstation) + ::: 1. **A hotkey workstation**—which is generally a server used for mining or validation—contains a hotkey private key in the `wallet_path` located in the `btcli config`, as well as a coldkey public key for the corresponding coldkey. Compromised hotkeys can damage your reputation if they are used to maliciously to submit inaccurate weights as a validator, or bad work as a miner. However, ownership of TAO or alpha stake can only be transferred with a coldkey, and a leaked hotkey can be swapped using the coldkey; therefore hotkey leaks are far less dangerous than coldkey leaks. - :::tip hotkey workstation - See [Hotkey workstation security](./getting-started/coldkey-hotkey-security#hotkey-workstation) - ::: + :::tip hotkey workstation + See [Hotkey workstation security](../keys/coldkey-hotkey-security#hotkey-workstation) + ::: ## Requirements for `btcli` functions + ### Coldkey Your coldkey is your primary, fully privileged key; important for all users. This key should be handled on a maximum security **coldkey workstation** only, to avoid catastrophic loss or malicious actions if compromised. -See [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security). +See [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security). Required for: + - Moving and transferring TAO - Managing stake (add/remove/move) - Creating hotkeys @@ -63,7 +65,8 @@ Required for: Hotkeys are used by **miners** and **validators** to sign transactions, and are required for governance. Required for: -- Running miners: + +- Running miners: - Serving requests from validators - Making on-chain data commitments (if applicable) - Running validators: @@ -82,23 +85,24 @@ Some operations require a TAO balance or alpha stake balance to execute. ### Validator Permit -To set weights, a validator must meet several requirements. See [Requirements for validation](./validators/#requirements-for-validation). +To set weights, a validator must meet several requirements. See [Requirements for validation](../validators/#requirements-for-validation). ### Senate requirements -See [Senate: Requirements](./senate#requirements) +See [Senate: Requirements](../governance/senate#requirements) ## `btcli` commands ### `config` The `btcli config ...` commands are used to configure `btcli`, including: + - selecting the targeted network (`finney` a.k.a. mainnet or `test` for test network) - setting the directory where your Bittensor wallet coldkeys and/or hotkeys are stored These commands don't require any permissions to run. Rather, you run these commands on all `btcli` workstations to initialize them. -See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey-security) +See: [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security)
btcli config @@ -125,22 +129,22 @@ See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey- The `wallet` command is required to provision keys to `btcli`, so it can access your wallet. This is essentially the equivalent of logging in/authentication. This is true for both coldkeys, which all users require, and hotkeys, which are required only by miners and validators as well as for advanced functions. :::tip mind your keys -See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey-security) +See: [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security) ::: -#### Provisioning keys +#### Provisioning keys -1. **`btcli wallet regen-coldkeypub`**: This initializes a wallet for a **permissionless workstation** with a public key only. It allows you to read all information about your wallet, which is public information. However, it doesn't allow you to sign any transactions and therefore doesn't allow you to make any *changes* to the state of the blockchain, including any of your balances or stakes. +1. **`btcli wallet regen-coldkeypub`**: This initializes a wallet for a **permissionless workstation** with a public key only. It allows you to read all information about your wallet, which is public information. However, it doesn't allow you to sign any transactions and therefore doesn't allow you to make any _changes_ to the state of the blockchain, including any of your balances or stakes. -1. **`new coldkey`** is used to initialize a coldkey workstation using a newly created *seed phrase*. This is a high security risk operation due to the inherent risk of handling the seed phrase. +1. **`new coldkey`** is used to initialize a coldkey workstation using a newly created _seed phrase_. This is a high security risk operation due to the inherent risk of handling the seed phrase. -1. **`regen coldkey`** is used to initialize a coldkey workstation using a pre-existing wallet's *seed phrase*. This is a high security risk operation due to the inherent risk of handling the seed phrase. +1. **`regen coldkey`** is used to initialize a coldkey workstation using a pre-existing wallet's _seed phrase_. This is a high security risk operation due to the inherent risk of handling the seed phrase. -1. **`new hotkey`** is used to initialize a hotkey workstation using a newly created *seed phrase*. This is a high security risk operation due to the inherent risk of handling the seed phrase. Hotkeys should be created on secure coldkey workstation and then carefully provisioned to working nodes for mining and validation. +1. **`new hotkey`** is used to initialize a hotkey workstation using a newly created _seed phrase_. This is a high security risk operation due to the inherent risk of handling the seed phrase. Hotkeys should be created on secure coldkey workstation and then carefully provisioned to working nodes for mining and validation. -1. **`regen hotkey`** is used to initialize a hotkey workstation using a pre-existing wallet's *seed phrase*. This is a high security risk operation due to the inherent risk of handling the seed phrase. +1. **`regen hotkey`** is used to initialize a hotkey workstation using a pre-existing wallet's _seed phrase_. This is a high security risk operation due to the inherent risk of handling the seed phrase. -#### Permissionless operations +#### Permissionless operations - **`btcli wallet balance`**: Displays a wallet balance. - **`btcli wallet overview`**: Displays a wallet overview. @@ -154,8 +158,8 @@ See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey- - **`sign`(with coldkey)** signs a message with the coldkey. #### Operations requiring hotkey private key: -- **`sign`** (with hotkey): sign a message with the hotkey +- **`sign`** (with hotkey): sign a message with the hotkey
`btcli wallet` @@ -171,7 +175,6 @@ See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey- #### `btcli wallet overview` #### `btcli wallet transfer` #### `btcli wallet inspect` -#### `btcli wallet faucet` #### `btcli wallet set-identity` #### `btcli wallet get-identity` #### `btcli wallet sign` @@ -185,54 +188,99 @@ See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey- #### `btcli wallet get_identity` #### `btcli w list` + #### `btcli w swap-hotkey` + #### `btcli w regen-coldkey` + #### `btcli w regen-coldkeypub` + #### `btcli w regen-hotkey` + #### `btcli w new-hotkey` + #### `btcli w new-coldkey` + #### `btcli w create` + #### `btcli w balance` + #### `btcli w overview` + #### `btcli w transfer` + #### `btcli w inspect` -#### `btcli w faucet` + #### `btcli w set-identity` + #### `btcli w get-identity` + #### `btcli w sign` + #### `btcli w swap_hotkey` + #### `btcli w regen_coldkey` + #### `btcli w regen_coldkeypub` + #### `btcli w regen_hotkey` + #### `btcli w new_hotkey` + #### `btcli w new_coldkey` + #### `btcli w set_identity` + #### `btcli w get_identity` + #### `btcli wallets list` + #### `btcli wallets swap-hotkey` + #### `btcli wallets regen-coldkey` + #### `btcli wallets regen-coldkeypub` + #### `btcli wallets regen-hotkey` + #### `btcli wallets new-hotkey` + #### `btcli wallets new-coldkey` + #### `btcli wallets create` + #### `btcli wallets balance` + #### `btcli wallets history` + #### `btcli wallets overview` + #### `btcli wallets transfer` + #### `btcli wallets inspect` -#### `btcli wallets faucet` + #### `btcli wallets set-identity` + #### `btcli wallets get-identity` + #### `btcli wallets sign` + #### `btcli wallets swap_hotkey` + #### `btcli wallets regen_coldkey` + #### `btcli wallets regen_coldkeypub` + #### `btcli wallets regen_hotkey` + #### `btcli wallets new_hotkey` + #### `btcli wallets new_coldkey` + #### `btcli wallets set_identity` + #### `btcli wallets get_identity` +
### `stake` @@ -240,7 +288,7 @@ See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey- Read operations require public keys. Write operations (stake add, move, remove...) require a coldkey private key. :::tip mind your keys -See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey-security) +See: [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security) :::
@@ -310,13 +358,21 @@ See: [Coldkey and Hotkey Workstation Security](./getting-started/coldkey-hotkey- #### `btcli su get` #### `btcli su senate` + #### `btcli su proposals` + #### `btcli su senate-vote` + #### `btcli su set-take` + #### `btcli su get-take` + #### `btcli su senate_vote` + #### `btcli su get_take` + #### `btcli su set_take` +
### `subnets` @@ -341,6 +397,7 @@ hyperparams are set with `btcli sudo`. Creating subnets requires a coldkey with sufficient balance. Miner and validator registering a hotkey uses a coldkey, has a TAO cost unless proof-of-work +
@@ -385,7 +442,7 @@ Miner and validator registering a hotkey uses a coldkey, has a TAO cost unless p Reading weights with `reveal` is permissionless. -To set weights with `commit`, a validator must meet several requirements. See [Requirements for validation](./#requirements-for-validation). +To set weights with `commit`, a validator must meet several requirements. See [Requirements for validation](#validator-permit).
`btcli weight` @@ -393,12 +450,17 @@ To set weights with `commit`, a validator must meet several requirements. See [R #### `btcli weights commit` #### `btcli wt reveal` + #### `btcli wt commit` + #### `btcli weight reveal` + #### `btcli weight commit` +
### `utils` #### `btcli utils convert` -`btcli utils convert` is a convenience command for performing conversions between minimal units (RAO) and TAO, or other chain-specific conversions. It is permissionless (no key required) because it performs no on-chain operation, just a local calculation. + +`btcli utils convert` is a convenience command for performing conversions between minimal units (RAO) and TAO, or other chain-specific conversions. It is permissionless (no key required) because it performs no on-chain operation, just a local calculation. diff --git a/docs/btcli/btcli-playground.md b/docs/btcli/btcli-playground.md index a155ddc9ae..f437c26809 100644 --- a/docs/btcli/btcli-playground.md +++ b/docs/btcli/btcli-playground.md @@ -20,7 +20,7 @@ This is not a secure code execution environment. This page is for practice/educa See: - [Handle your Seed Phrase/Mnemonic Securely](../keys/handle-seed-phrase) -- [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security) +- [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security) ::: ## Import wallets and check balances. diff --git a/docs/btcli/btcli.md b/docs/btcli/btcli.md new file mode 100644 index 0000000000..3ae76eb0ff --- /dev/null +++ b/docs/btcli/btcli.md @@ -0,0 +1,3324 @@ +--- +title: "Bittensor CLI: btcli Reference Document" +--- + +# Bittensor CLI: `btcli` Reference Document + +Command line interface (CLI) for Bittensor. Uses the values in the configuration file. These values can be overriden by passing them explicitly in the command line. + +See [Getting Started](../getting-started/install-btcli.md) to install `btcli`. + +:::note Transaction Fees +Many BTCLI operations incur transaction fees. See [Transaction Fees in Bittensor](../learn/fees.md) for details. +::: + +Command line interface (CLI) for Bittensor. Uses the values in the configuration file. These values can be +overriden by passing them explicitly in the command line. + +**Usage**: + +```bash +btcli [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--version`: Show BTCLI version. +- `--commands`: Show BTCLI commands. +- `--debug`: Saves the debug log from the last used command. +- `--install-completion`: Install completion for the current shell. +- `--show-completion`: Show completion for the current shell, to copy it or customize the installation. +- `--help`: Show this message and exit. + +**Commands**: + +- `config`: Config commands, aliases: `c`, `conf` +- `wallet`: Wallet commands, aliases: `wallets`, `w` +- `stake`: Stake commands, alias: `st` +- `sudo`: Sudo commands, alias: `su` +- `subnets`: Subnets commands, alias: `s`, `subnet` +- `weights`: Weights commands, aliases: `wt`, `weight` +- `crowd`: Crowdloan commands, aliases: `cr`, `crowdloan` +- `liquidity`: Liquidity commands, aliases: `l` +- `utils` +- `view`: HTML view commands + +## `btcli config` + +**Usage**: + +```bash +btcli config [OPTIONS] COMMAND [ARGS]... + +aliases: conf, c +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `set`: Sets or updates configuration values in the BTCLI config file. +- `get`: Prints the current config file in a table. +- `clear`: Clears the fields in the config file and sets them to 'None'. + +### `btcli config set` + +Sets or updates configuration values in the BTCLI config file. + +This command allows you to set default values that will be used across all BTCLI commands. + +**Usage:** + +Interactive mode: +`btcli config set` + +Set specific values: +`btcli config set --wallet-name default --network finney` +`btcli config set --safe-staking --rate-tolerance 0.1` + +Note: + +- Network values can be network names (e.g., 'finney', 'test') or websocket URLs +- Rate tolerance is specified as a decimal (e.g., 0.05 for 0.05%) +- Changes are saved to `~/.bittensor/btcli.yaml` +- Use `btcli config get` to view current settings + +**Usage**: + +```console +btcli config set [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--cache`, `--cache`/`--no-cache`, `--no_cache` | | Disable caching of some commands. This will disable the `--reuse-last` and `--html` flags on commands such as `subnets metagraph`, `stake show` and `subnets list`. | +| `--tolerance` | FLOAT | Set the rate tolerance percentage for transactions (e.g. 0.1 for 0.1%) | +| `--safe-staking`, `--safe`/`--no-safe-staking`, `--unsafe` | | Enable or disable safe staking mode. | +| `--allow-partial-stake`, `--partial`, `--allow`/`--no-allow-partial-stake`, `--no-partial`, `--not-allow` | | Allow or prevent partial stakes | +| `--dashboard-path`, `--dashboard_path`, `--dash_path`, `--dash.path` | TEXT | Path to save the dashboard HTML file. For example: `~/.bittensor/dashboard`. | +| `--help` | | Show this message and exit. | + +### `btcli config get` + +Prints the current config file in a table. + +**Usage**: + +```console +btcli config get [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| -------- | ---- | --------------------------- | +| `--help` | | Show this message and exit. | + +### `btcli config clear` + +Clears the fields in the config file and sets them to 'None'. + + - To clear the 'chain' and 'network' fields: + + ``` + btcli config clear --chain --network + ``` + + - To clear your config entirely: + + ``` + btcli config clear --all + ``` + +**Usage**: + +```console +btcli config clear [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--cache` | | Disable caching of some commands. This will disable the `--reuse-last` and `--html` flags on commands such as `subnets metagraph`, `stake show` and `subnets list`. | +| `--tolerance` | | | +| `--safe-staking`, `--safe`/`--no-safe-staking`, `--unsafe` | | Enable or disable safe staking mode. | +| `--allow-partial-stake`, `--partial`, `--allow`/`--no-allow-partial-stake`, `--no-partial`, `--not-allow` | | Allow or prevent partial stakes | +| `--all` | | Clears the entire config. | +| `--dashboard-path`, `--dashboard_path`, `--dash_path`, `--dash.path` | TEXT | Path to save the dashboard HTML file. For example: `~/.bittensor/dashboard`. | +| `--help` | | Show this message and exit. | + +## `btcli view` + +Display html dashboard with subnets list, stake, and neuron information. + +**Usage**: + +```console +btcli view [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `dashboard`: Display html dashboard with subnets list, stake, and neuron information. + +### `btcli view dashboard` + +Display html dashboard with subnets list, stake, and neuron information. + +**Usage**: + +```bash +btcli view dashboard +``` + +**Options**: + +| Option | Type | Description | +| -------- | ---- | --------------------------- | +| `--help` | | Show this message and exit. | + +## `btcli wallet` + +**Usage**: + +```console +btcli wallet [OPTIONS] COMMAND [ARGS]... + +aliases: w, wallets +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `list`: Displays all the wallets and their corresponding hotkeys that are located in the wallet path specified in the config. +- `associate_hotkey`: Associate a hotkey with a wallet(coldkey). +- `swap-hotkey`: Swap hotkeys of a given wallet on the blockchain. +- `swap-coldkey`: Schedule a coldkey swap for a wallet. +- `swap-check`: Check the status of scheduled coldkey swaps. +- `regen-coldkey`: Regenerate a coldkey for a wallet on the Bittensor blockchain network. +- `regen-coldkeypub`: Regenerates the public part of a coldkey (`coldkeypub.txt`) for a wallet. +- `regen-hotkey`: Regenerates a hotkey for a wallet. +- `regen-hotkeypub`: Regenerates the public part of a hotkey (`hotkeypub.txt`) for a wallet. +- `new-hotkey`: Create a new hotkey for a wallet. +- `new-coldkey`: Create a new coldkey. +- `create`: Create a complete wallet by setting up both coldkey and hotkeys. +- `balance`: Check the balance of the wallet. +- `overview`: Displays a detailed overview of the user's registered accounts on the Bittensor network. +- `transfer`: Send TAO tokens from one wallet to another wallet on the Bittensor network. +- `set-identity`: Create or update the on-chain identity of a coldkey or a hotkey on the Bittensor network. +- `get-identity`: Shows the identity details of a user's coldkey or hotkey. +- `sign`: Allows users to sign a message with the provided wallet or wallet hotkey. +- `verify`: Verify a message signature using the signer's public key or SS58 address. + +### `btcli wallet list` + +Displays all the wallets and their corresponding hotkeys that are located in the wallet path specified in the config. + +The output display shows each wallet and its associated `ss58` addresses for the coldkey public key and any hotkeys. The output is presented in a hierarchical tree format, with each wallet as a root node and any associated hotkeys as child nodes. The `ss58` address is displayed for each coldkey and hotkey that is not encrypted and exists on the device. + +Upon invocation, the command scans the wallet directory and prints a list of all the wallets, indicating whether the +public keys are available (`?` denotes unavailable or encrypted keys). + +``` +btcli wallet list --path ~/.bittensor +``` + +Note: This command is read-only and does not modify the filesystem or the blockchain state. It is intended for use with the Bittensor CLI to provide a quick overview of the user's wallets. + +**Usage**: + +```console +btcli wallet list [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| ----------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--help` | | Show this message and exit. | + +### `btcli wallet associate-hotkey` + +This command is used to associate a hotkey with a wallet(coldkey). + +**Example** + +```sh +btcli wallet associate-hotkey --hotkey-name hotkey_name +``` + +```sh +btcli wallet associate-hotkey --hotkey-ss58 5DkQ4... +``` + +**Usage:** + +```sh +btcli w associate-hotkey [OPTIONS] + +alias: associate_hotkey +``` + +**Options** + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey name or SS58 address of the hotkey. | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--help` | | Show this message and exit. | +| | + +### `btcli wallet swap-hotkey` + +Swap hotkeys of a given wallet on the blockchain. For a registered key pair, for example, a (coldkeyA, hotkeyA) pair, this command swaps the hotkeyA with a new, unregistered, hotkeyB to move the original registration to the (coldkeyA, hotkeyB) pair. + +:::info + +- Make sure that your original key pair (coldkeyA, hotkeyA) is already registered. +- Make sure that you use a newly created hotkeyB in this command. A hotkeyB that is already registered cannot be used in this command. +- Finally, note that this command requires a fee of 1 TAO for recycling and this fee is taken from your wallet (coldkeyA). + ::: + +**Example:** + +``` +btcli wallet swap_hotkey destination_hotkey_name --wallet-name your_wallet_name --wallet-hotkey original_hotkey +``` + +**Usage**: + +```console +btcli wallet swap-hotkey [OPTIONS] [DESTINATION_HOTKEY_NAME] + +alias: swap_hotkey +``` + +**Arguments**: + +- `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| ` --all-netuids`/`--no-all-netuids`, | | Use all netuids | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | +| | + +### `btcli wallet swap-coldkey` + +This command allows you to schedule a coldkey swap for a wallet. You can either provide a new wallet name, or SS58 address. + +**Example** + +```sh +btcli wallet swap-coldkey --new-wallet my_new_wallet +``` + +```sh +btcli wallet swap-coldkey --new-coldkey-ss58 5Dk...X3q +``` + +**Usage:** + +```sh +btcli wallet swap-coldkey [OPTIONS] + +alias: swap_coldkey +``` + +**Options** + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--new-coldkey`, `--new-coldkey-ss58`, `--new-wallet`, `--new` | TEXT | SS58 address of the new coldkey that will replace the current one. | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--force`, `--force-swap`, `-f` | | Force the swap even if the new coldkey is already scheduled for a swap. | +| `--help` | | Show this message and exit. | +| | + +### `btcli wallet swap-check` + +This command checks the status of scheduled coldkey swaps. It can be used in one of three ways: + +- Show all pending swaps using the `--all` flag. +- Check status of a specific wallet's swap or SS58 address. +- Check detailed swap status with block number using the `--block` flag. + +**Example** + +Show all pending swaps: + +```sh +btcli wallet swap-check --all +``` + +Check specific wallet's swap: + +```sh + btcli wallet swap-check --wallet-name my_wallet +``` + +Check swap using SS58 address: + +```sh + btcli wallet swap-check --ss58 5DkQ4... +``` + +Check swap details with block number: + +```sh + btcli wallet swap-check --wallet-name my_wallet --block 12345 +``` + +**Usage:** + +```sh +btcli wallet swap-check [OPTIONS] + +alias: swap_check +``` + +**Options** +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--block` | INTEGER | Block number where the swap was scheduled. | +| `--all` | | Show all pending coldkey swaps | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--help` | | Show this message and exit. | +| | + +### `btcli wallet regen-coldkey` + +Regenerate a coldkey for a wallet on the Bittensor blockchain network. + +This command is used to create a new instance of a coldkey from an existing mnemonic, seed, or JSON file. + +**Usage:** + +Users can specify a mnemonic, a seed string, or a JSON file path to regenerate a coldkey. The command supports optional password protection for the generated key. + +**Example:** + +``` +btcli wallet regen-coldkey --mnemonic "word1 word2 ... word12" +``` + +:::info +This command is critical for users who need to regenerate their coldkey either for recovery or for security reasons. +::: + +**Usage**: + +```console +btcli wallet regen-coldkey [OPTIONS] + +alias: regen_coldkey +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--mnemonic` | TEXT | Mnemonic used to regenerate your key. | +| `--seed`, | TEXT | Seed hex string used to regenerate your key. | +| `--json`, `-j` | TEXT | Path to a JSON file containing the encrypted key backup. | +| `--json-password`, | TEXT | Password to decrypt the JSON file.key. | +| `--use-password`/`--no-use-password `, | | Set this to `True` to protect the generated Bittensor key with a password. | +| `--overwrite`/`--no-overwrite` | | Overwrite the existing wallet file with the new one. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet regen-coldkeypub` + +Regenerates the public part of a coldkey (`coldkeypub.txt`) for a wallet. + +Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your `coldkeypub.txt` that you have on another machine to regenerate the `coldkeypub.txt` on this new machine. + +**Usage:** + +The command requires either a public key in hexadecimal format or an `SS58` address from the existing `coldkeypub.txt` from old machine to regenerate the coldkeypub on the new machine. + +**Example:** + +``` +btcli wallet regen_coldkeypub --ss58_address 5DkQ4... +``` + +:::info +This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old `coldkeypub.txt` for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. +::: +**Usage**: + +```console +btcli wallet regen-coldkeypub [OPTIONS] + +alias: regen_coldkeypub +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--public-key-hex`, | TEXT | The public key in hex format. | +| `--ss58`, `--ss58-address`, | TEXT | The SS58 address of the coldkey. | +| `--overwrite`/`--no-overwrite` | | Overwrite the existing wallet file with the new one. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet regen-hotkey` + +Regenerates a hotkey for a wallet. + +Similar to regenerating a coldkey, this command creates a new hotkey from a mnemonic, seed, or JSON file. + +**Usage:** + +Users can provide a mnemonic, seed string, or a JSON file to regenerate the hotkey. The command supports optional password protection and can overwrite an existing hotkey. + +``` +btcli wallet regen_hotkey --seed 0x1234... +``` + +:::info +This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery. +It should be used with caution to avoid accidental overwriting of existing keys. +::: + +**Usage**: + +```console +btcli wallet regen-hotkey [OPTIONS] + +alias: regen_hotkey +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--mnemonic` | TEXT | Mnemonic used to regenerate your key. | +| `--seed`, | TEXT | Seed hex string used to regenerate your key. | +| `--json`, `-j` | TEXT | Path to a JSON file containing the encrypted key backup. | +| `--json-password`, | TEXT | Password to decrypt the JSON file.key. | +| `--use-password`/`--no-use-password`, | | Set this to `True` to protect the generated Bittensor key with a password. | +| `--overwrite`/`--no-overwrite` | | Overwrite the existing wallet file with the new one. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet regen-hotkeypub` + +This command regenerates the public part of a hotkey (hotkeypub.txt) for a wallet. Use this command when you need to move machine for subnet mining. Use the public key or SS58 address from your hotkeypub.txt that you have on another machine to regenerate the hotkeypub.txt on this new machine. + +**Usage** +The command requires either a public key in hexadecimal format or an `SS58` address from the existing `hotkeypub.txt` from old machine to regenerate the hotkeypub on the new machine. + +**Example:** + +```sh +btcli wallet regen-hotkeypub --ss58_address 5DkQ4... +``` + +**Usage** + +```sh +btcli wallet regen-hotkeypub [OPTIONS] + +alias: regen_hotkeypub +``` + +:::info +This command is particularly useful for users who need to regenerate their hotkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old `hotkeypub.txt` for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. +::: + +**Options** + +| Option | Type | Description | +| ------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--public-key-hex`, | TEXT | The public key in hex format. | +| `--ss58`, `--ss58-address`, | TEXT | The SS58 address of the coldkey. | +| `--overwrite`/`--no-overwrite` | | Overwrite the existing wallet file with the new one. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet new-hotkey` + +Create a new hotkey for a wallet. + +**Usage:** + +This command is used to generate a new hotkey for managing a neuron or participating in a subnet. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting the +existing hotkey. + +**Example:** + +``` +btcli wallet new-hotkey --n_words 24 +``` + +:::info +This command is useful to create additional hotkeys for different purposes, such as running multiple subnet miners or subnet validators or separating operational roles within the Bittensor network. +::: + +**Usage**: + +```console +btcli wallet new-hotkey [OPTIONS] + +alias: new_hotkey +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--n-words`, `--n_words` | INTEGER | The number of words used in the mnemonic. | +| `--use-password`/`--no-use-password `, | | Set this to `True` to protect the generated Bittensor key with a password. | +| `--uri` | TEXT | Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie') | +| `--overwrite`/`--no-overwrite` | | Overwrite the existing wallet file with the new one. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet new-coldkey` + +Create a new coldkey. A coldkey is required for holding TAO balances and performing high-value transactions. + +**Usage:** + +The command creates a new coldkey. It provides options for the mnemonic word count, and supports password protection. It also allows overwriting an existing coldkey. + +**Example:** + +``` +btcli wallet new_coldkey --n_words 15 +``` + +:::info +This command is crucial for users who need to create a new coldkey for enhanced security or as part of setting up a new wallet. It is a foundational step in establishing a secure presence on the Bittensor network. +::: + +**Usage**: + +```console +btcli wallet new-coldkey [OPTIONS] + +alias: new_coldkey +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--n-words`, `--n_words` | INTEGER | The number of words used in the mnemonic. | +| `--use-password`/`--no-use-password `, | | Set this to `True` to protect the generated Bittensor key with a password. | +| `--uri` | TEXT | Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie') | +| `--overwrite`/`--no-overwrite` | | Overwrite the existing wallet file with the new one. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet create` + +Create a complete wallet by setting up both coldkey and hotkeys. + +**Usage:** + +The command creates a new coldkey and hotkey. It provides an option for mnemonic word count. It supports password protection for the coldkey and allows overwriting of existing keys. + +**Example:** + +``` +btcli wallet create --n-words 21 +``` + +Note: This command is for new users setting up their wallet for the first time, or for those who wish to completely renew their wallet keys. It ensures a fresh start with new keys for secure and effective participation in the Bittensor network. + +**Usage**: + +```console +btcli wallet create [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--n-words` | INTEGER | The number of words used in the mnemonic. | +| `--use-password`/`--no-use-password `, | | Set this to `True` to protect the generated Bittensor key with a password. | +| `--uri` | TEXT | Create wallet from uri (e.g. 'Alice', 'Bob', 'Charlie') | +| `--overwrite`/`--no-overwrite` | | Overwrite the existing wallet file with the new one. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet balance` + +Check the balance of the wallet. This command shows a detailed view of the wallet's coldkey balances, including free and staked balances. + +You can also pass multiple ss58 addresses of coldkeys to check their balance (using --ss58). + +**Example:** + +- To display the balance of a single wallet, use the command with the `--wallet-name` argument and provide the wallet name: + + ``` + btcli w balance --wallet-name WALLET + ``` + +- To use the default config values, use: + + ``` + btcli w balance + ``` + +- To display the balances of all your wallets, use the `--all` argument: + + ``` + btcli w balance --all + ``` + +- To display the balances of ss58 addresses, use the `--ss58` argument: + + ``` + btcli w balance --ss58 <ss58_address> --ss58 <ss58_address> + ``` + +**Usage**: + +```console +btcli wallet balance [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--ss58`, `--ss58-address`, | TEXT | The SS58 address of the coldkey. | +| `--all`, `-a` | | Whether to display the balances for all the wallets. | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet overview` + +Displays a detailed overview of the user's registered accounts on the Bittensor network. + +This command compiles and displays comprehensive information about each neuron associated with the user's wallets, including both hotkeys and coldkeys. It is especially useful for users managing multiple accounts or looking for a summary of their network activities and stake distributions. + +**Usage:** + +``` +btcli wallet overview +``` + +``` +btcli wallet overview --all +``` + +Note: This command is read-only and does not modify the blockchain state or account configuration. +It provides a quick and comprehensive view of the user's network presence, making it useful for monitoring account status, +stake distribution, and overall contribution to the Bittensor network. + +**Usage**: + +```console +btcli wallet overview [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--all`, `-a` | | See an overview for all the wallets | +| `--sort-by`, `--sort_by` | TEXT | Sort the hotkeys by the specified column title. For example: name, uid, axon. | +| `--sort-order`, `--sort_order` | TEXT | Sort the hotkeys in the specified order (ascending/asc or descending/desc/reverse). | +| `--include-hotkeys`, `-in` | TEXT | Hotkeys to include. Specify by name or ss58 address. If left empty, all hotkeys, except those in the `--exclude-hotkeys`, will be included. | +| `--exclude-hotkeys`, `-ex` | TEXT | Hotkeys to exclude. Specify by name or ss58 address. If left empty, all hotkeys, except those in the `--include-hotkeys`, will be excluded. | +| `--netuids`, `--netuid`, `-n` | TEXT | Set the netuid(s) to exclude. Separate multiple netuids with a comma, for example: `-n 0,1,2`. | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet transfer` + +Send TAO tokens from one wallet to another wallet on the Bittensor network. + +This command is used for transactions between different wallet accounts, enabling users to send tokens to other +participants on the network. The command displays the user's current balance before prompting for the amount +to transfer (send), ensuring transparency and accuracy in the transaction. + +**Usage:** + +The command requires that you specify the destination address (public key) and the amount of TAO you want transferred. +It checks if sufficient balance exists in your wallet and prompts for confirmation before proceeding with the transaction. + +**Example:** + +``` +btcli wallet transfer --dest 5Dp8... --amount 100 +``` + +Note: This command is used for executing token transfers within the Bittensor network. Users should verify the destination address and the TAO amount before confirming the transaction to avoid errors or loss of funds. + +**Usage**: + +```console +btcli wallet transfer [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--destination`, `--dest`, `-d` | TEXT | Destination address (ss58) of the wallet (coldkey). | +| `--amount`, `-a` | FLOAT | Amount (in TAO) to transfer. | +| `--all` | | Transfer all available balance. | +| `--all` | | Whether to display the balances for all the wallets. | +| `--period`, `-era` | INTEGER | Length (in blocks) for which the transaction should be valid. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet set-identity` + +Create or update the on-chain identity of a coldkey or a hotkey on the Bittensor network. Incurs a 1 TAO transaction fee. + +The on-chain identity includes attributes such as display name, legal name, web URL, PGP fingerprint, and contact information, among others. + +The command prompts the user for the identity attributes and validates the input size for each attribute. It provides an option to update an existing validator hotkey identity. If the user consents to the transaction cost, the identity is updated on the blockchain. + +Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey `ss58` address for the identity to be updated. + +If the user does not have a hotkey, the coldkey address is used by default. If setting a validator identity, the hotkey will be used by default. If the user is setting an identity for a subnet, the coldkey will be used by default. + +**Example:** + +``` +btcli wallet set_identity +``` + +:::info +This command should only be used if the user is willing to incur the a recycle fee associated with setting an identity on the blockchain. It is a high-level command that makes changes to the blockchain state and should not be used programmatically as part of other scripts or applications. +::: + +**Usage**: + +```console +btcli wallet set-identity [OPTIONS] + +alias: set_identity +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--name` | TEXT | The display name for the identity. | +| `--web-url`, `--web` | TEXT | The web URL for the identity. | +| `--image-url`, `--image` | TEXT | The image URL for the identity. | +| `--discord` | TEXT | The Discord handle for the identity. | +| `--description` | TEXT | The description for the identity. | +| `--additional` | TEXT | Additional details for the identity. | +| `--github` | TEXT | The GitHub repository for the identity. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet get-identity` + +Shows the identity details of a user's coldkey or hotkey. + +The command displays the information in a table format showing: + +- Address: The `ss58` address of the queried key. + +- Item: Various attributes of the identity such as stake, rank, and trust. + +- Value: The corresponding values of the attributes. + +**Example:** + +```sh +btcli wallet get_identity --key <s58_address> +``` + +:::info +This command is primarily used for informational purposes and has no side effects on the blockchain network state. +::: + +**Usage**: + +```console +btcli wallet get-identity [OPTIONS] + +alias: get_identity +``` + +**Options**: + +| Option | Type | Description | +| -------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--ss58`, `--coldkey_ss58`, `--coldkey.ss58_address`, `--coldkey.ss58`, `--key`, `-k ` | TEXT | Coldkey address of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet sign` + +Allows users to sign a message with the provided wallet or wallet hotkey. Use this command to easily prove your ownership of a coldkey or a hotkey. + +**Usage:** + +Using the provided wallet (coldkey), the command generates a signature for a given message. + +**Example:** + +```sh +btcli wallet sign --wallet-name default --message '{"something": "here", "timestamp": 1719908486}' +``` + +```sh +btcli wallet sign --wallet-name default --wallet-hotkey hotkey --message '{"something": "here", "timestamp": 1719908486}' +``` + +**Usage**: + +```console +btcli wallet sign [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------------------------------------------- | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--use-hotkey` / `--no-use-hotkey` | | If specified, the message will be signed by the hotkey. If not specified, the user will be prompted. | +| `--message` | TEXT | The message to encode and sign. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli wallet verify` + +Verify a message signature using the signer's public key or SS58 address. This command allows you to verify that a message was signed by the owner of a specific address. + +**Usage:** + +Provide the original message, the signature (in hex format), and either the SS58 address or public key of the signer to verify the signature. + +**Example:** + +```sh +btcli wallet verify --message "Hello world" --signature "0xabc123..." --address "5GrwvaEF..." +``` + +```sh +btcli wallet verify -m "Test message" -s "0xdef456..." -p "0x1234abcd..." +``` + +**Usage**: + +```console +btcli wallet verify [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| -------------------------------------- | ---- | --------------------------------------------------------------- | +| `--message` | TEXT | The message that was signed. [default: None] | +| `--signature`, `-s` | TEXT | The signature to verify. (hex format) [default: None] | +| `--address`, `--public-key` `-a`, `-p` | TEXT | SS58 address or public key (hex) of the signer. [default: None] | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +## `btcli stake` + +**Usage**: + +```console +btcli stake [OPTIONS] COMMAND [ARGS]... + +alias: st +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `add`: Stake TAO to one or more hotkeys on specific netuids with your coldkey. +- `remove`: Unstake TAO from one or more hotkeys and transfer them back to the user's coldkey wallet. +- `list`: Display detailed stake information for a wallet across all subnets. +- `move`: Move staked TAO between hotkeys while keeping the same coldkey ownership. +- `transfer`: Transfer stake between coldkeys while keeping the same hotkey ownership. +- `swap`: Swap stake between different subnets while keeping the same coldkey-hotkey pair ownership. +- `child`: Child Hotkey commands, alias: `children` +- `children` + +### `btcli stake add` + +Stake TAO to one or more hotkeys on specific or multiple netuids with your coldkey. + +Stakes are always added through your coldkey's free balance. For stake movement, see the [`btcli stake move`](#btcli-stake-move) command. + +Common Examples: + +1. Interactive staking (guided prompts): + + ```sh + btcli stake add + ``` + +2. Safe staking with rate tolerance of 10% with partial transaction disabled: + + ```sh + btcli stake add --amount 100 --netuid 1 --safe --tolerance 0.1 --no-partial + ``` + +3. Allow partial stake if rates change with tolerance of 10%: + + ```sh + btcli stake add --amount 300 --safe --partial --tolerance 0.1 + ``` + +4. Unsafe staking with no rate protection: + + ```sh + btcli stake add --amount 300 --netuid 1 --unsafe + ``` + +5. Stake to multiple hotkeys: + + ```sh + btcli stake add --amount 200 --include-hotkeys hk_ss58_1,hk_ss58_2,hk_ss58_3 + ``` + +6. Stake the same amount of TAO into multiple subnets: + + ```sh + btcli stake add -n 4,14,64 --amount 100 + ``` + +7. Stake all balance to a subnet: + ```sh + btcli stake add --all --netuid 3 + ``` + +Safe Staking Parameters:--safe: Enables rate tolerance checks +`--tolerance`: Maximum % rate change allowed (0.05 = 5%) +`--partial`: Complete partial stake if rates exceed tolerance + +**Usage**: + +```console +btcli stake add [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `--all-tokens`, `--all`, `-a` | | When set, the command stakes all the available TAO from the coldkey. | +| `--amount` | FLOAT | The amount of TAO to stake | +| `--include-hotkeys`, `--hotkey-ss58-address`, `-in` | TEXT | Specifies hotkeys by name or ss58 address to stake to. For example, `-in hk1,hk2` | +| `--exclude-hotkeys`, `-ex` | TEXT | Specifies hotkeys by name or ss58 address to not to stake to (use this option only with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` | +| `--all-hotkeys`/ `--no-all-hotkeys` | | When set, this command stakes to all hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. | +| `--netuids`, `--netuid`, `-n` | TEXT | Netuid(s) to for which to add stake. Specify multiple netuids by separating with a comma, for example: `-n 0,1,2`. | +| `--all-netuids`/ `--no-all-netuid` | | Use all netuids. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--tolerance`, `--rate-tolerance` | FLOAT | Set the rate tolerance percentage for transactions (e.g. 0.1 for 0.1%) | +| `--safe-staking`, `--safe`/`--no-safe-staking`, `--unsafe` | | Enable or disable safe staking mode. | +| `--allow-partial-stake`, `--partial`, `--allow`/`--no-allow-partial-stake`, `--no-partial`, `--not-allow` | | Allow or prevent partial stakes | +| `--period`, `-era` | INTEGER | Length (in blocks) for which the transaction should be valid. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli stake auto` + +Display auto-stake destinations for a wallet across all subnets. + +**Usage:** + +```bash +btcli stake auto [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--ss58`, `--coldkey_ss58`, `--coldkey.ss58_address`, `--coldkey.ss58` | | Coldkey address of the wallet | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli stake set-auto` + +Set the auto-stake destination hotkey for a coldkey. + +**Usage:** + +```bash +btcli stake set-auto [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli stake remove` + +Unstake TAO from one or more hotkeys and transfer them back to the user's coldkey wallet. + +This command is used to withdraw TAO or Alpha stake from different hotkeys. + +Common Examples: + +1. Interactive unstaking (guided prompts): + + ``` + btcli stake remove + ``` + +2. Safe unstaking with 10% rate tolerance: + + ``` + btcli stake remove --amount 100 --netuid 1 --safe --tolerance 0.1 + ``` + +3. Allow partial unstake if rates change: + + ``` + btcli stake remove --amount 300 --safe --partial + ``` + +4. Unstake from multiple hotkeys: + + ``` + btcli stake remove --amount 200 --include-hotkeys hk1,hk2,hk3 + ``` + +5. Unstake all from a hotkey: + + ``` + btcli stake remove --all + ``` + +6. Unstake all Alpha from a hotkey and stake to Root: + ``` + btcli stake remove --all-alpha + ``` + +Safe Staking Parameters: +`--safe`: Enables rate tolerance checks during unstaking +`--tolerance`: Max allowed rate change (0.05 = 5%) +`--partial`: Complete partial unstake if rates exceed tolerance + +**Usage**: + +```console +btcli stake remove [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid`, | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--all-netuids`/ `--no-all-netuid` | | Use all netuids. | +| `--unstake-all`, `--all` | | When set, this command unstakes all staked TAO + Alpha from the all hotkeys. | +| `--unstake-all-alpha`, `--all-alpha` | | When set, this command unstakes all staked Alpha from the all hotkeys. | +| `--amount`, `-a` | FLOAT | The amount of TAO to unstake | +| `--hotkey-ss58-address` | TEXT | The ss58 address of the hotkey to unstake from. | +| `--include-hotkeys`, `-in` | TEXT | Specifies hotkeys by name or ss58 address to unstake from. For example, `-in hk1,hk2` | +| `--exclude-hotkeys`, `-ex` | TEXT | Specifies hotkeys by name or ss58 address to not to unstake from (use this option only with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` | +| `--all-hotkeys`/ `--no-all-hotkeys` | | When set, this command unstakes from all hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. | +| `--tolerance`, `--rate-tolerance` | FLOAT | Set the rate tolerance percentage for transactions (e.g. 0.1 for 0.1%) | +| `--safe-staking`, `--safe`/`--no-safe-staking`, `--unsafe` | | Enable or disable safe staking mode. | +| `--allow-partial-stake`, `--partial`, `--allow`/`--no-allow-partial-stake`, `--no-partial`, `--not-allow` | | Allow or prevent partial stakes | +| `--period`, `-era` | INTEGER | Length (in blocks) for which the transaction should be valid. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--interactive`, `-t` | | Enter interactive mode for unstaking. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli stake list` + +Display detailed stake information for a wallet across all subnets. + +Shows stake allocations, exchange rates, and emissions for each hotkey. + +Common Examples: + +1. Basic stake overview: + +``` +btcli stake list --wallet.name my_wallet +``` + +2. Live updating view with refresh: + +``` +btcli stake list --wallet.name my_wallet --live +``` + +3. View specific coldkey by address: + +``` +btcli stake list --ss58 5Dk...X3q +``` + +4. Verbose output with full values: + +``` +btcli stake list --wallet.name my_wallet --verbose +``` + +**Usage**: + +```console +btcli stake list [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| -------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--ss58`, `--coldkey_ss58`, `--coldkey.ss58_address`, `--coldkey.ss58`, `--key`, `-k ` | TEXT | Coldkey address of the wallet | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--live` | | Display live view of the table | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli stake move` + +Move staked TAO between hotkeys while keeping the same coldkey ownership. + +This command allows you to: + +- Move stake from one hotkey to another hotkey +- Move stake between different subnets +- Keep the same coldkey ownership + +You can specify: + +- The origin subnet (--origin-netuid) +- The destination subnet (--dest-netuid) +- The destination hotkey (--dest-hotkey) +- The amount to move (--amount) + +If no arguments are provided, an interactive selection menu will be shown. + +**Example:** + +``` +btcli stake move +``` + +**Usage**: + +```console +btcli stake move [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| -------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `from`, `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Validator hotkey or SS58 where the stake is currently located. | +| `--origin-netuid` | INTEGER | Origin netuid. | +| `--dest-netuid` | INTEGER | Destination netuid. | +| `to`, `--dest-ss58`, `--dest` | TEXT | Destination validator hotkey SS58. | +| `--amount` | FLOAT | The amount of TAO to stake | +| `--stake-all`, `--all` | | Stake all. | +| `--period`, `-era` | INTEGER | Length (in blocks) for which the transaction should be valid. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli stake transfer` + +Transfer stake between coldkeys while keeping the same hotkey ownership. + +This command allows you to: + +- Transfer stake from one coldkey to another coldkey +- Keep the same hotkey ownership +- Transfer stake between different subnets + +You can specify: + +- The origin subnet (--origin-netuid) +- The destination subnet (--dest-netuid) +- The destination wallet/address (--dest) +- The amount to transfer (--amount) + +If no arguments are provided, an interactive selection menu will be shown. + +**Example:** + +Transfer 100 TAO from subnet 1 to subnet 2: + +``` +btcli stake transfer --origin-netuid 1 --dest-netuid 2 --dest wallet2 --amount 100 +``` + +Using SS58 address: + +``` +btcli stake transfer --origin-netuid 1 --dest-netuid 2 --dest 5FrLxJsyJ5x9n2rmxFwosFraxFCKcXZDngEP9H7qjkKgHLcK --amount 100 +``` + +**Usage**: + +```console +btcli stake transfer [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--origin-netuid` | INTEGER | The netuid to transfer stake from. | +| `--dest-netuid` | INTEGER | The netuid to transfer stake to. | +| `--dest-ss58`, `--dest` | TEXT | The destination wallet name or SS58 address to transfer stake to. | +| `--amount` | FLOAT | The amount of stake to transfer. | +| `--stake-all`, `--all` | | Stake all. | +| `--period`, `-era` | INTEGER | Length (in blocks) for which the transaction should be valid. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli stake swap` + +Swap stake between different subnets while keeping the same coldkey-hotkey pair ownership. + +This command allows you to: + +- Move stake from one subnet to another subnet +- Keep the same coldkey ownership +- Keep the same hotkey ownership + +You can specify: + +- The origin subnet (--origin-netuid) +- The destination subnet (--dest-netuid) +- The amount to swap (--amount) + +If no arguments are provided, an interactive selection menu will be shown. + +**Example:** + +Swap 100 TAO from subnet 1 to subnet 2: + +``` +btcli stake swap --wallet-name default --wallet-hotkey default --origin-netuid 1 --dest-netuid 2 --amount 100 +``` + +**Usage**: + +```console +btcli stake swap [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--origin-netuid`, `-o` | INTEGER | The netuid to swap stake from. | +| `--dest-netuid`, `-d` | INTEGER | The netuid to swap stake to. | +| `--amount`, `-a` | FLOAT | The amount of stake to swap. | +| `--swap-all`, `--all` | | Swap all available stake. | +| `--period`, `-era` | INTEGER | Length (in blocks) for which the transaction should be valid. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--wait-for-inclusion`/ `--no-wait-for-inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait-for-finalization`/ `--no-wait-for-finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli stake child` + +**Usage**: + +```console +btcli stake child [OPTIONS] COMMAND [ARGS]... + +alias: children +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `get`: Get all the child hotkeys on a specified subnet. +- `set`: Set child hotkeys on a specified subnet (or all). Overrides currently set children. +- `revoke`: Remove all children hotkeys on a specified subnet (or all). +- `take`: Get and set your child hotkey take on a specified subnet. + +#### `btcli stake child get` + +Get all the child hotkeys on a specified subnet. + +Users can specify the subnet and see the child hotkeys and the proportion that is given to them. This command is used to view the authority delegated to different hotkeys on the subnet. + +**Example:** + +``` +btcli stake child get --netuid 1 +``` + +``` +btcli stake child get --all-netuids +``` + +**Usage**: + +```console +btcli stake child get [OPTIONS] + +alias: children +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--netuid` | INTEGER | The netuid of the subnet. | +| `--all-netuids`, `--all`, `--allnetuids` | | When set, gets the child hotkeys from all the subnets. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +#### `btcli stake child set` + +Set child hotkeys on specified subnets. + +Users can specify the 'proportion' to delegate to child hotkeys (ss58 address). The sum of proportions cannot be greater than 1. + +This command is used to delegate authority to different hotkeys, securing their position and influence on the subnet. + +**Example:** + +``` +btcli stake child set -c 5FCL3gmjtQV4xxxxuEPEFQVhyyyyqYgNwX7drFLw7MSdBnxP -c 5Hp5dxxxxtGg7pu8dN2btyyyyVA1vELmM9dy8KQv3LxV8PA7 --hotkey default --netuid 1 -p 0.3 -p 0.7 +``` + +**Usage**: + +```console +btcli stake child set [OPTIONS] + +alias: children +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------ | +| `--children`, `-c` | TEXT | Enter child hotkeys (ss58) | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--netuid` | INTEGER | The netuid of the subnet in the network. | +| `--all-netuids`/`--no-all-netuids` | | Use all netuids. | +| `--proportions`, `--prop` | FLOAT | Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) | +| `--wait-for-inclusion`/ `--no-wait-for-inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait-for-finalization`/ `--no-wait-for-finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +#### `btcli stake child revoke` + +Remove all children hotkeys on a specified subnet. + +This command is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet. + +**Example:** + +``` +btcli stake child revoke --hotkey <parent_hotkey> --netuid 1 +``` + +**Usage**: + +```console +btcli stake child revoke [OPTIONS] + +alias: children +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--netuid` | INTEGER | The netuid of the subnet in the network. | +| `--all-netuids`, `--all`, `--allnetuids` | | When this flag is used it sets child hotkeys on all the subnets. | +| `--wait-for-inclusion`/ `--no-wait-for-inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait-for-finalization`/ `--no-wait-for-finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +#### `btcli stake child take` + +Get and set your child hotkey take on a specified subnet. + +The child hotkey take must be between 0 - 18%. + +**Example:** + +To get the current take value, do not use the '--take' option: + +``` +btcli stake child take --child-hotkey-ss58 --netuid 1 +``` + +To set a new take value, use the '--take' option: + +``` +btcli stake child take --child-hotkey-ss58 --take 0.12 --netuid 1 +``` + +**Usage**: + +```console +btcli stake child take [OPTIONS] + +alias: children +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--child-hotkey-ss58` | TEXT | The hotkey SS58 to designate as child (not specifying will use the provided wallet's hotkey) | +| `--netuid` | INTEGER | The netuid of the subnet in the network. | +| `--all-netuids`, `--all`, `--allnetuids` | | When this flag is used it sets child hotkeys on all the subnets. | +| `--take` | FLOAT | Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. | +| `--wait-for-inclusion`/ `--no-wait-for-inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait-for-finalization`/ `--no-wait-for-finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +## `btcli sudo` + +**Usage**: + +```console +btcli sudo [OPTIONS] COMMAND [ARGS]... + +alias: su +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `set`: Used to set hyperparameters for a specific subnet. +- `get`: Shows a list of the hyperparameters for the specified subnet. +- `senate`: Shows the Senate members of the Bittensor's governance protocol. +- `proposals`: View active proposals for the senate in the Bittensor's governance protocol. +- `senate-vote`: Cast a vote on an active proposal in Bittensor's governance protocol. +- `set-take`: Allows users to change their delegate take percentage. +- `get-take`: Allows users to check their delegate take percentage. +- `trim`: Allows subnet owners to trim UIDs on their subnet to a specified max number of netuids. + +### `btcli sudo set` + +Used to set hyperparameters for a specific subnet. + +This command allows subnet owners to modify hyperparameters such as its tempo, emission rates, and other hyperparameters. + +**Example:** + +``` +btcli sudo set --netuid 1 --param tempo --value 400 +``` + +**Usage**: + +```console +btcli sudo set [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--netuid` | INTEGER | The netuid of the subnet in the network. | +| `--param`, `--parameter` | TEXT | The subnet hyperparameter to set | +| `--value` | TEXT | Value to set the hyperparameter to. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli sudo get` + +Shows a list of the hyperparameters for the specified subnet. + +**Example:** + +``` +btcli sudo get --netuid 1 +``` + +**Usage**: + +```console +btcli sudo get [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli sudo senate` + +Shows the Senate members of the Bittensor's governance protocol. + +This command lists the delegates involved in the decision-making process of the Bittensor network, showing their names and wallet addresses. This information is crucial for understanding who holds governance roles within the network. + +**Example:** + +``` +btcli sudo senate +``` + +**Usage**: + +```console +btcli sudo senate [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli sudo proposals` + +View active proposals for the senate in the Bittensor's governance protocol. + +This command displays the details of ongoing proposals, including proposal hashes, votes, thresholds, and proposal data. + +**Example:** + +``` +btcli sudo proposals +``` + +**Usage**: + +```console +btcli sudo proposals [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli sudo senate-vote` + +Cast a vote on an active proposal in Bittensor's governance protocol. + +This command is used by Senate members to vote on various proposals that shape the network's future. Use `btcli sudo proposals` to see the active proposals and their hashes. + +**Usage:** +The user must specify the hash of the proposal they want to vote on. The command then allows the Senate member to cast a 'Yes' or 'No' vote, contributing to the decision-making process on the proposal. This command is crucial for Senate members to exercise their voting rights on key proposals. It plays a vital role in the governance and evolution of the Bittensor network. + +**Example:** + +``` +btcli sudo senate-vote --proposal <proposal_hash> +``` + +**Usage**: + +```console +btcli sudo senate-vote [OPTIONS] + +alias: senate_vote +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ---- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--proposal`, `--proposal-hash` | TEXT | The hash of the proposal to vote on. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--vote-aye/--vote-nay` | | The vote cast on the proposal | +| `--help` | | Show this message and exit. | + +### `btcli sudo set-take` + +Allows users to change their delegate take percentage. + +This command can be used to update the delegate takes. To run the command, the user must have a configured wallet with both hotkey and coldkey. +The command makes sure the new take value is within 0-18% range. + +**Example:** + +``` +btcli sudo set-take --wallet-name my_wallet --wallet-hotkey my_hotkey +``` + +**Usage**: + +```console +btcli sudo set-take [OPTIONS] + +alias: set_take +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ----- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--take` | FLOAT | The new take value. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli sudo get-take` + +Allows users to check their delegate take percentage. + +This command can be used to fetch the delegate take of your hotkey. + +**Example:** + +``` +btcli sudo get-take --wallet-name my_wallet --wallet-hotkey my_hotkey +``` + +**Usage**: + +```console +btcli sudo get-take [OPTIONS] + +alias: get_take +``` + +**Options**: + +| Option | Type | Description | +| ------------------------------------------------------------------------------------------ | ---- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey`, `--hotkey-ss58` | TEXT | Hotkey name or SS58 address of the hotkey | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli sudo trim` + +Allows subnet owners to trim UIDs on their subnet to a specified max number of netuids. + +**EXAMPLE** + +```bash +btcli sudo trim --netuid 95 --wallet-name my_wallet --wallet-hotkey my_hotkey --max 64 +``` + +**Usage:** + +```bash +btcli sudo trim [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--max`, `--max-uids` | INTEGER | The maximum number of allowed uids to which to trim | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--help` | | Show this message and exit. | + +## `btcli subnets` + +**Usage**: + +```console +btcli subnets [OPTIONS] COMMAND [ARGS]... + +aliases: subnet, s +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `mechanisms`: Subnet mechanism commands, alias: `mech` +- `hyperparameters`: Shows a list of the hyperparameters for the specified subnet. +- `list`: List all subnets and their detailed information. +- `burn-cost`: Shows the required amount of TAO to be recycled for creating a new subnet, i.e., cost of registering a new subnet. +- `create`: Registers a new subnet on the network. +- `pow-register`: Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW). +- `register`: Register a neuron (a subnet validator or a subnet miner) in the specified subnet by recycling some TAO. +- `metagraph`: Displays detailed information about a... +- `show`: Displays detailed information about a subnet including participants and their state. +- `price`: Shows the historical price of a subnet for the past 4 hours. +- `check-start`: Checks if a subnet's emission schedule can be started. +- `set-identity`: Get the identity information for a subnet. +- `get-identity`: Set or update the identity information for a subnet. +- `set-symbol`: Allows the user to update their subnet symbol to a different available symbol. The full list of available symbols can be found here: https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/symbols.rs#L8 + +### `btcli subnet mechanisms` + +**Usage**: + +```console +btcli s mechanisms [OPTIONS] COMMAND [ARGS]... + +alias: mech +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `count`: Display how many mechanisms are registered under a subnet. +- `set`: Configure how many mechanisms are registered for a subnet. +- `emissions`: Display the current emission split across mechanisms for a subnet. +- `split-emissions`: Update the emission split across mechanisms for a subnet. + +#### `btcli subnet mechanisms count` + +Display how many mechanisms are registered under a subnet. Includes the base mechanism (index 0). Helpful for verifying the active mechanism counts in a subnet. + +```bash +btcli subnet mechanisms count --netuid 12 +``` + +**Usage:** + +```bash +btcli subnet mechanisms count [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +#### `btcli subnet mechanisms set` + +Configure how many mechanisms are registered for a subnet. + +The base mechanism at index 0 and new ones are incremented by 1. + +Common Examples: + +1. Prompt for the new mechanism count interactively: + +```bash +btcli subnet mechanisms set --netuid 12 +``` + +2. Set the count to 2 using a specific wallet: + +```bash +btcli subnet mechanisms set --netuid 12 --count 2 --wallet.name my_wallet --wallet.hotkey admin +``` + +**Usage:** + +```bash +btcli subnet mechanisms set [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--count`, `--mech-count` | INTEGER | Number of mechanisms to set for the subnet. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +#### `btcli subnet mechanisms emissions` + +Display the current emission split across mechanisms for a subnet. Shows raw `U16` weights alongside percentage shares for each mechanism. Useful for verifying the emission split in a subnet. + +```bash +btcli subnet mechanisms emissions --netuid 12 +``` + +**Usage:** + +```bash +btcli subnet mechanisms emissions [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +#### `btcli subnet mechanisms split-emissions` + +Update the emission split across mechanisms for a subnet. + +Accepts comma-separated weights (`U16` values or percentages). When `--split` is omitted and prompts remain enabled, you will be guided interactively and the CLI automatically normalises the weights. + +Common Examples: + +1. Configure the split interactively: + +```bash +btcli subnet mechanisms split-emissions --netuid 12 +``` + +2. Apply a 70/30 distribution in one command: + +```bash +btcli subnet mechanisms split-emissions --netuid 12 --split 70,30 --wallet.name my_wallet --wallet.hotkey admin +``` + +**Usage:** + +```bash +btcli subnet mechanisms split-emissions [OPTIONS] + +alias: emissions-split +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--split` | TEXT | Comma-separated relative weights for each mechanism (normalised automatically). | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets hyperparameters` + +Shows a list of the hyperparameters for the specified subnet. + +**Example:** + +``` +btcli sudo get --netuid 1 +``` + +**Usage**: + +```console +btcli subnets hyperparameters [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets list` + +List all subnets and their detailed information. + +Common Examples: + +1. List all subnets: + +``` +btcli subnets list +``` + +2. List all subnets in live mode: + +``` +btcli subnets list --live +``` + +**Output Columns:** + +- **Netuid** - Subnet identifier number +- **Name** - Subnet name with currency symbol (τ/α/β etc) +- **Price** (τ_in/α_in) - Exchange rate (TAO per alpha token) +- **Market Cap** (α \* Price) - Total value in TAO (alpha tokens × price) +- **Emission** (τ) - TAO rewards emitted per block to subnet +- **P** (τ_in, α_in) - Pool reserves (Tao reserves, alpha reserves) in liquidity pool +- **Stake** (α_out) - Total staked alpha tokens across all hotkeys (alpha outstanding) +- **Supply** (α) - Circulating alpha token supply +- **Tempo** (k/n) - Block interval for subnet updates + +**Example:** + +``` +btcli subnets list +``` + +**Usage**: + +```console +btcli subnets list [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--live` | | Display live view of the table | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets burn-cost` + +Shows the required amount of TAO to be recycled for creating a new subnet, i.e., cost of registering a new subnet. + +The current implementation anneals the cost of creating a subnet over a period of two days. If the displayed cost is unappealing to you, check back in a day or two to see if it has decreased to a more affordable level. + +**Example:** + +``` +btcli subnets burn_cost +``` + +**Usage**: + +```console +btcli subnets burn-cost [OPTIONS] + +alias: burn_cost +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets create` + +Creates a new subnet on the network. + +This command allows you to create a new subnet and set the subnet's identity. +You also have the option to set your own identity after the registration is complete. + +Common Examples: + +1. Interactive subnet creation: + +``` +btcli subnets create +``` + +2. Create with GitHub repo and contact email: + +``` +btcli subnets create --subnet-name MySubnet --github-repo https://github.com/myorg/mysubnet --subnet-contact team@mysubnet.net +``` + +**Usage**: + +```console +btcli subnets create [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--subnet-name` | TEXT | Name of the subnet. | +| `--github-repo`, `repo` | TEXT | The GitHub repository URL. | +| `--subnet-contact`, `--contact`, `--email` | TEXT | Contact email for subnet. | +| `--subnet-url`, `--url` | TEXT | The web URL for the subnet. | +| `--discord-handle`, `discord` | TEXT | The Discord handle for the subnet. | +| `--description` | TEXT | The description for the subnet. | +| `--additional-info` | TEXT | Additional details for the subnet. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets pow-register` + +Register a neuron (a subnet validator or a subnet miner) using Proof of Work (POW). + +This method is an alternative registration process that uses computational work for securing a neuron's place on the subnet. + +The command starts by verifying the existence of the specified subnet. If the subnet does not exist, it terminates with an error message. On successful verification, the POW registration process is initiated, which requires solving computational puzzles. + +The command also supports additional wallet and subtensor arguments, enabling further customization of the registration process. + +**Example:** + +``` +btcli pow_register --netuid 1 --num_processes 4 --cuda +``` + +Note: This command is suitable for users with adequate computational resources to participate in POW registration. +It requires a sound understanding of the network's operations and POW mechanics. Users should ensure their systems meet the necessary hardware and software requirements, particularly when opting for CUDA-based GPU acceleration. + +This command may be disabled by the subnet owner. For example, on netuid 1 this is permanently disabled. + +**Usage**: + +```console +btcli subnets pow-register [OPTIONS] + +alias pow_register +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------- | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--processors` | INTEGER | Number of processors to use for POW registration. | +| `-u`, `--update-interval` | INTEGER | The number of nonces to process before checking for the next block during registration | +| `--output-in-place`/`--no-output-in-place` | | Whether to output the registration statistics in-place. | +| `--verbose`, `-v` | | Enable verbose output. | +| `--use-cuda`, `--cuda`/`--no-use-cuda`, `--no-cuda` | | Set the flag to use CUDA for POW registration. | +| `--dev-id`, `-d` | INTEGER | Set the CUDA device id(s), in the order of the device speed (0 is the fastest). | +| `--threads-per-block`, `-tpb` | INTEGER | Set the number of threads per block for CUDA. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--help` | | Show this message and exit. | + +### `btcli subnets register` + +Register a neuron (a subnet validator or a subnet miner) in the specified subnet by recycling some TAO. + +Before registering, the command checks if the specified subnet exists and whether the user's balance is sufficient to cover the registration cost. + +The registration cost is determined by the current recycle amount for the specified subnet. If the balance is insufficient or the subnet does not exist, the command will exit with an error message. + +**Example:** + +``` +btcli subnets register --netuid 1 +``` + +**Usage**: + +```console +btcli subnets register [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid`, | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--period`, `-era` | INTEGER | Length (in blocks) for which the transaction should be valid. Note that it is possible that if you use an era for this transaction that you may pay a different fee to register than the one stated. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets metagraph` + +Inspect the metagraph for a subnet. + +Shows miners, validators, stake, ranks, emissions, and other runtime stats. When multiple mechanisms exist, the CLI prompts for one unless `--mechid` is supplied. Netuid `0` always uses mechid `0`. + +Common Examples: + +1. Inspect the mechanism with prompts for selection: + +```bash +btcli subnets metagraph --netuid 12 +``` + +2. Pick mechanism 1 explicitly: + +```bash +btcli subnets metagraph --netuid 12 --mechid 1 +``` + +**Usage**: + +```console +btcli subnets metagraph [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid`, | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--mechid`, `--mech-id`, `--mech_id`, `--mechanism_id`, `--mechanism-id` | INTEGER | Mechanism ID within the subnet (defaults to 0). | +| `--sort` | | Sort the subnets by uid. | +| `--quiet` | | Display only critical information on the console. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets show` + +Inspect the metagraph for a subnet. + +Shows miners, validators, stake, ranks, emissions, and other runtime stats. When multiple mechanisms exist, the CLI prompts for one unless `--mechid` is supplied. Netuid `0` always uses mechid `0`. + +Common Examples: + +1. Inspect the mechanism with prompts for selection: + +```bash +btcli subnets show --netuid 12 +``` + +2. Pick mechanism 1 explicitly: + +```bash +btcli subnets show --netuid 12 --mechid 1 +``` + +**Usage**: + +```console +btcli subnets show [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid`, | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--mechid`, `--mech-id`, `--mech_id`, `--mechanism_id`, `--mechanism-id` | INTEGER | Mechanism ID within the subnet (defaults to 0). | +| `--sort` | | Sort the subnets by uid. | +| `--quiet` | | Display only critical information on the console. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets price` + +Shows the historical price of a subnet for the past 4 hours. + +This command displays the historical price of a subnet for the past 4 hours. + +- If the `--all` flag is used, the command will display the price for all subnets in html format. +- If the `--html` flag is used, the command will display the price in an HTML chart. +- If the `--log-scale` flag is used, the command will display the price in log scale. +- If no html flag is used, the command will display the price in the cli. + +**Example:** + +```bash +btcli subnets price --netuid 1 +``` + +```bash +btcli subnets price --netuid 1 --html --log +``` + +```bash +btcli subnets price --all --html +``` + +```bash +btcli subnets price --netuids 1,2,3,4 --html +``` + +**Usage**: + +```bash +btcli subnets price [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuids`, `--netuid`, `-n` | TEXT | Netuids to show the price for. Separate multiple netuids with a comma, for example: `-n 0,1,2`. | +| `--interval-hours`, `--interval` | INTEGER | The number of hours to show the historical price for. | +| `--all-netuids`, `--all` | | Show the price for all subnets. | +| `--log-scale`, `--log` | | Show the price in log scale. | +| `--current` | | Show only the current data, and no historical data. | +| `--html` | | Display the table as HTML in the browser. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets check-start` + +Checks if a subnet's emission schedule can be started. This command verifies if a subnet's emission schedule can be started based on the subnet's registration block. + +**Example:** + +```bash +btcli subnets check_start --netuid 1 +``` + +**Usage** + +```bash +btcli subnets check-start [OPTIONS] + +alias check_start +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--help` | | Show this message and exit. | + +### `btcli subnets set-identity` + +Set or update the identity information for a subnet. This command allows subnet owners to set or update identity information like name, GitHub repo, contact details, etc. + +**Examples:** + +1. Interactive subnet identity setting: + +```bash +btcli subnets set-identity --netuid 1 +``` + +2. Set subnet identity with specific values: + +```bash +btcli subnets set-identity --netuid 1 --subnet-name MySubnet --github-repo https://github.com/myorg/mysubnet --subnet-contact team@mysubnet.net +``` + +**Usage**: + +```sh +btcli subnets set-identity [OPTIONS] + +alias: set_identity +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--subnet-name`, `--name` | TEXT | Name of the subnet. | +| `--github-repo`, `repo` | TEXT | The GitHub repository URL. | +| `--subnet-contact`, `--contact`, `--email` | TEXT | Contact email for subnet. | +| `--subnet-url`, `--url` | TEXT | The web URL for the subnet. | +| `--discord-handle`, `discord` | TEXT | The Discord handle for the subnet. | +| `--description` | TEXT | The description for the subnet. | +| `--additional-info` | TEXT | Additional details for the subnet. | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets get-identity` + +Get the identity information for a subnet. This command displays the identity information of a subnet including name, GitHub repo, contact details, etc. + +**Examples:** + +```sh +btcli subnets get-identity --netuid 1 +``` + +**Usage**: + +```sh +btcli subnets get-identity [OPTIONS] + +alias: get_identity +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli subnets set-symbol` + +Allows the user to update their subnet symbol to a different available symbol. The full list of available symbols can be found here: +https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/symbols.rs#L8 + +**EXAMPLE** + +```bash +btcli subnets set-symbol --netuid 1 シ +``` + +:::info +JSON OUTPUT: +If --json-output is used, the output will be in the following schema: `{success: bool, message: str}` +::: + +**Usage:** + +```bash +btcli subnets set-symbol [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--help` | | Show this message and exit. | + +## `btcli weights` + +**Usage**: + +```console +btcli weights [OPTIONS] COMMAND [ARGS]... + +aliases: wt, weight +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `reveal`: Reveal weights for a specific subnet. +- `commit`: Commit weights for specific subnet. + +### `btcli weights reveal` + +Reveal weights for a specific subnet. + +You must specify the netuid, the UIDs you are interested in, and weights you wish to reveal. + +**Example:** + +``` +btcli wt reveal --netuid 1 --uids 1,2,3,4 --weights 0.1,0.2,0.3,0.4 --salt 163,241,217,11,161,142,147,189 +``` + +**Usage**: + +```console +btcli weights reveal [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------- | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--uids`, `-u` | TEXT | Corresponding UIDs for the specified netuid, e.g. -u 1,2,3 .. | +| `--weights`, `-w` | TEXT | Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the specified UIDs. | +| `--salt`, `-s` | TEXT | Corresponding salt for the hash function, e.g. -s 163,241,217 ... | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli weights commit` + +Commit weights for specific subnet. + +Use this command to commit weights for a specific subnet. You must specify the netuid, the UIDs you are interested in, and the weights you wish to commit. + +**Example:** + +``` +btcli wt commit --netuid 1 --uids 1,2,3,4 --w 0.1,0.2,0.3 +``` + +Note: This command is used to commit weights for a specific subnet and requires the user to have the necessary +permissions. + +**Usage**: + +```console +btcli weights commit [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------- | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `-p`, `--wallet-path`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `-H`, `--hotkey`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--uids`, `-u` | TEXT | Corresponding UIDs for the specified netuid, e.g. -u 1,2,3 .. | +| `--weights`, `-w` | TEXT | Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the specified UIDs. | +| `--salt`, `-s` | TEXT | Corresponding salt for the hash function, e.g. -s 163,241,217 ... | +| `--prompt`, `--prompt`, `--no-prompt`, `--yes`, `--no_prompt`, `-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +## `btcli crowd` + +**Usage:** + +```sh +btcli crowdloan [OPTIONS] COMMAND [ARGS]... + +alias: cr, crowdloan +``` + +**Options:** + +`--help`: Show this message and exit. + +**Commands:** + +- `create`: Start a new crowdloan campaign for fundraising or subnet leasing. +- `contribute` : Contribute TAO to an active crowdloan. +- `withdraw` : Withdraw contributions from a non-finalized crowdloan. +- `finalize` Finalize a successful crowdloan that has reached its cap. +- `update` : Update one mutable field on a non-finalized crowdloan. +- `refund`: Refund contributors of a non-finalized crowdloan. +- `dissolve`: Dissolve a crowdloan after all contributors have been refunded. +- `list`: List crowdloans together with their funding progress and key metadata. +- `info`: Display detailed information about a specific crowdloan. + +### `btcli crowd create` + +Start a new crowdloan campaign for fundraising or subnet leasing. + +Create a crowdloan that can either: + +1. Raise funds for a specific address (general fundraising) +2. Create a new leased subnet where contributors receive emissions + +**EXAMPLES** + +General fundraising: + +```bash +btcli crowd create --deposit 10 --cap 1000 --target-address 5D... +``` + +Subnet leasing with 30% emissions for contributors: + +```bash +btcli crowd create --subnet-lease --emissions-share 30 +``` + +Subnet lease ending at block 500000: + +```bash +btcli crowd create --subnet-lease --emissions-share 25 --lease-end-block 500000 +``` + +**Usage:** + +```bash +btcli crowd create [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--deposit` | FLOAT | Initial deposit in TAO to secure the crowdloan. | +| `--min-contribution`, `--min_contribution` | FLOAT | Minimum contribution amount in TAO. | +| `--cap` | INTEGER | Maximum amount in TAO the crowdloan will raise. | +| `--duration` | INTEGER | Crowdloan duration in blocks. | +| `--target-address`, `--target` | TEXT | Optional target SS58 address to receive the raised funds (for fundraising type). | +| `--subnet-lease/--fundraising` | | Create a subnet leasing crowdloan (True) or general fundraising (False). | +| `--emissions-share`, `--emissions` | INTEGER | Percentage of emissions for contributors (0-100) for subnet leasing. | +| `--lease-end-block`, `--lease-end` | INTEGER | Block number when subnet lease ends (omit for perpetual lease). | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli crowd contribute` + +Contribute TAO to an active crowdloan. + +This command allows you to contribute TAO to a crowdloan that is currently accepting contributions. +The contribution will be automatically adjusted if it would exceed the crowdloan's cap. + +**EXAMPLES** + +```bash +btcli crowd contribute --id 0 --amount 100 +``` + +```bash +btcli crowd contribute --id 1 +``` + +**Usage:** + +```bash +btcli crowd contribute [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--crowdloan-id`, `--crowdloan_id`, `--id` | INTEGER | The ID of the crowdloan to display | +| `--amount`, `-a` | FLOAT | Amount to contribute in TAO | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli crowd withdraw` + +Withdraw contributions from a non-finalized crowdloan. + +:::info +Non-creators can withdraw their full contribution. Creators can only withdraw amounts above their initial deposit. +::: + +**Usage:** + +```bash +btcli crowd withdraw [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--crowdloan-id`, `--crowdloan_id`, `--id` | INTEGER | The ID of the crowdloan to withdraw from | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli crowd finalize` + +Finalize a successful crowdloan that has reached its cap. + +:::info +Only the creator can finalize. This will transfer funds to the target +address (if specified) and execute any attached call (e.g., subnet creation). +::: + +**Usage:** + +```bash +btcli crowd finalize [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--crowdloan-id`, `--crowdloan_id`, `--id` | INTEGER | The ID of the crowdloan to finalize | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli crowd update` + +Update one mutable field on a non-finalized crowdloan. + +:::info + +Only the creator can invoke this. You may change the minimum contribution, the end block, or the cap in a single call. When no flag is provided an interactive prompt guides you through the update and validates the input against the chain constants (absolute minimum contribution, block-duration +bounds, etc.). +::: + +**Usage:** + +```bash +btcli crowd update [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--crowdloan-id`, `--crowdloan_id`, `--id` | INTEGER | The ID of the crowdloan to update | +| `--min-contribution`, `--min` | FLOAT | Update the minimum contribution amount (in TAO) | +| `--end`, `--end-block` | INTEGER | Update the end block number | +| `--cap` | FLOAT | Update the cap amount (in TAO) | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli crowd refund` + +Refund contributors of a non-finalized crowdloan. + +:::info +The crowdloan creator may call this once the crowdloan is no longer wanted. Each call refunds up to the on-chain `RefundContributorsLimit` contributors (currently 50) excluding the creator. Run it repeatedly until everyone except the creator has been reimbursed. + +::: + +**Usage:** + +```bash +btcli crowd refund [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--crowdloan-id`, `--crowdloan_id`, `--id` | INTEGER | The ID of the crowdloan to refund | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli crowd dissolve` + +Dissolve a crowdloan after all contributors have been refunded. + +Only the creator can dissolve. The crowdloan must be non-finalized and the raised balance must equal the creator's own contribution (i.e., all other contributions have been withdrawn or refunded). Dissolving returns the creator's deposit and removes the crowdloan from storage. + +:::info +If there are funds still available other than the creator's contribution, +you can run `btcli crowd refund` to refund the remaining contributors. +::: + +**Usage:** + +```bash +btcli crowd dissolve [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--crowdloan-id`, `--crowdloan_id`, `--id` | INTEGER | The ID of the crowdloan to dissolve | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--wait_for_inclusion` | | If `True`, waits until the transaction is included in a block. | +| `--wait_for_finalization` | | If `True`, waits until the transaction is finalized on the blockchain. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli crowd list` + +List crowdloans together with their funding progress and key metadata. + +Shows every crowdloan on the selected network, including current status (Active, Funded, Closed, Finalized), whether it is a subnet leasing crowdloan, or a general fundraising crowdloan. + +Use `--verbose` for full-precision amounts and longer addresses. + +**EXAMPLES** + +```bash +btcli crowd list +``` + +```bash +btcli crowd list --verbose +``` + +**Usage:** + +```bash +btcli crowd list [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli crowd info` + +Display detailed information about a specific crowdloan. + +Includes funding progress, target account, and call details among other information. + +**EXAMPLES** + +```bash +btcli crowd info --id 0 +``` + +```bash +btcli crowd info --id 1 --verbose +``` + +**Usage:** + +```bash +btcli crowd info [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--crowdloan-id`, `--crowdloan_id`, `--id` | INTEGER | The ID of the crowdloan to display | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +## `btcli liquidity` + +**Usage:** + +```sh +btcli liquidity [OPTIONS] COMMAND [ARGS]... + +alias: l +``` + +Options: + +`--help`: Show this message and exit. + +Commands: + +- `add`: Add liquidity to the swap (as a combination of TAO + Alpha). +- `list`: Displays liquidity positions in given subnet. +- `modify`: Modifies the liquidity position for the given subnet. +- `remove`: Remove liquidity from the swap (as a combination of TAO + Alpha). + +### `btcli liquidity add` + +Add liquidity to the swap (as a combination of TAO + Alpha). + +**Usage:** + +```bash +btcli liquidity add [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| ---------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--liquidity` | FLOAT | Amount of liquidity to add to the subnet. | +| `--price-low`, `--price_low`, `--liquidity-price-low`, `--liquidity_price_low` | FLOAT | Low price for the adding liquidity position. | +| `--price-high`, `--price_high`, `--liquidity-price-high`, `--liquidity_price_high` | FLOAT | High price for the adding liquidity position. | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli liquidity list` + +Displays liquidity positions in given subnet. + +**Usage:** + +```bash +btcli liquidity list [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli liquidity modify` + +Modifies the liquidity position for the given subnet. + +**Usage:** + +```bash +btcli liquidity modify [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--position-id`, `--position_id` | INTEGER | Position ID for modification or removing. | +| `--liquidity-delta`, `--liquidity_delta` | FLOAT | Liquidity amount for modification. | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +### `btcli liquidity remove` + +Remove liquidity from the swap (as a combination of TAO + Alpha). + +**Usage:** + +```bash +btcli liquidity remove [OPTIONS] +``` + +**Parameters:** + +| Options | Type | Description | +| --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ | +| `--network`, `--subtensor.network`, `--chain`, `--subtensor.chain_endpoint` | TEXT | The subtensor network to connect to. Default: finney. | +| `--wallet-name`, `--name`, `--wallet_name`, `--wallet.name` | TEXT | Name of the wallet. | +| `--wallet-path`, `-p`, `--wallet_path`, `--wallet.path` | TEXT | Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. | +| `--hotkey`, `-H`, `--wallet_hotkey`, `--wallet-hotkey`, `--wallet.hotkey` | TEXT | Hotkey of the wallet | +| `--netuid` | INTEGER | The netuid of the subnet in the network, (e.g. 1). | +| `--position-id`, `--position_id` | INTEGER | Position ID for modification or removal. | +| `--all`, `--a` | | Whether to remove all liquidity positions for given subnet. | +| `--prompt/--no-prompt`, ` /--yes`, ` /--no_prompt`, ` /-y` | | Enable or disable interactive prompts. | +| `--quiet` | | Display only critical information on the console. | +| `--verbose` | | Enable verbose output. | +| `--json-output`, `--json-out` | | Outputs the result of the command as JSON. | +| `--help` | | Show this message and exit. | + +## `btcli utils` + +**Usage**: + +```console +btcli utils [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `convert`: Allows for converting between tao and rao... +- `latency`: This command will give you the latency of all finney-like network in additional to any additional networks you specify via the '--network' flag. + +### `btcli utils convert` + +Allows for converting between tao and rao using the specified flags + +**Usage**: + +```sh +btcli utils convert [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| -------- | ----- | --------------------------- | +| `--rao` | TEXT | Convert amount from Rao | +| `--tao` | FLOAT | Convert amount from Tao | +| `--help` | | Show this message and exit. | + +### `btcli utils latency` + +This command will give you the latency of all finney-like network in addition to any additional networks you specify via the `--network` flag + +The results are three-fold. One column is the overall time to initialise a connection, send the requests, and wait for the results. The second column measures single ping-pong speed once connected. The third makes a real world call to fetch the chain head. + +**Example:** + +```sh +btcli utils latency --network ws://189.234.12.45 --network wss://mysubtensor.duckdns.org +``` + +**Usage**: + +```sh +btcli utils latency [OPTIONS] +``` + +**Options**: + +| Option | Type | Description | +| ----------- | ---- | ---------------------------------------------------------- | +| `--network` | TEXT | Network(s) to test for the best connection [default: None] | +| `--help` | | Show this message and exit. | + +--- diff --git a/docs/btcli/overview.md b/docs/btcli/overview.md index 20cc4c597b..d15782ddfe 100644 --- a/docs/btcli/overview.md +++ b/docs/btcli/overview.md @@ -4,10 +4,10 @@ title: "Bittensor CLI Overview" # Bittensor CLI Overview -The Bittensor command line interface (CLI), `btcli`, provides the simplest way to interact with the Bittensor network and its subnets from the command line. This includes managing [wallets (coldkeys and hotkeys)](../getting-started/wallets), TAO balances, transfer, staking and unstaking functions, node registration, governance functions, and more. - +The Bittensor command line interface (CLI), `btcli`, provides the simplest way to interact with the Bittensor network and its subnets from the command line. This includes managing [wallets (coldkeys and hotkeys)](../keys/wallets), TAO balances, transfer, staking and unstaking functions, node registration, governance functions, and more. See: + - [Install `btcli`](../getting-started/install-btcli) - [Managing Stake with BTCLI](../staking-and-delegation/managing-stake-btcli.md) -- [`btcli reference document`](../btcli.md) \ No newline at end of file +- [`btcli reference document`](./btcli.md) diff --git a/docs/concepts/bittensor-networks.md b/docs/concepts/bittensor-networks.md new file mode 100644 index 0000000000..bb7a16c8ed --- /dev/null +++ b/docs/concepts/bittensor-networks.md @@ -0,0 +1,18 @@ +--- +title: "Bittensor Networks" +--- + +# Bittensor Networks + +The below table presents Bittensor networks and a few details: + +| DESCRIPTION | MAINNET | TESTNET | LOCALNET | +| :---------------------------- | :------------------------------------------ | :--------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| **Chain URL** | wss://entrypoint-finney.opentensor.ai:443 | wss://test.finney.opentensor.ai:443 | ws://127.0.0.1:9944 | +| **Example Usage** | `btcli wallet swap_hotkey --network finney` | `btcli wallet swap_hotkey --network test` | `btcli wallet swap_hotkey --network local` | +| **Block processing** | One block every 12 seconds | One block every 12 seconds | One block every 0.25s seconds in fast blocks mode and one block every 12s in non-fast blocks mode. | +| **Mainnet Archive** | wss://archive.chain.opentensor.ai:443 | None | None | +| **Mainnet Lite** | wss://lite.chain.opentensor.ai:443 | None | None | +| **Experimental Mainnet Lite** | wss://lite.finney.test.opentensor.ai:443 | None | None | +| **Network Purpose** | Transactions with financial value | Test transactions with no value, constrained by tokenomics | Development and testing in fully user-controlled environment | +| **Test TAO** | None | Available on request (not compatible with devnet test TAO) | Available in Alice wallet. See [Access the Alice account](../local-build/provision-wallets#access-the-alice-account). | diff --git a/docs/subnets/bt-logging-levels.md b/docs/concepts/bt-logging-levels.md similarity index 100% rename from docs/subnets/bt-logging-levels.md rename to docs/concepts/bt-logging-levels.md diff --git a/docs/concepts/commit-reveal.md b/docs/concepts/commit-reveal.md new file mode 100644 index 0000000000..b1320268e9 --- /dev/null +++ b/docs/concepts/commit-reveal.md @@ -0,0 +1,151 @@ +--- +title: "Commit Reveal" +--- + +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Commit Reveal + +This page describes the **Commit Reveal** feature: a configurable waiting period that elapses between when consensus weights set by subnet validators are first committed, and when they are revealed publicly and included in [Yuma Consensus](../learn/yuma-consensus). + + +## Overview + +In each Bittensor subnet, each validator scores—or _'weights'_—each miner, producing what is referred to as a [weight vector](../resources/glossary.md#weight-vector). The weight vectors for each validator in a subnet are combined into a weight matrix. This matrix determines emissions to miners in the subnet based on the consensus evaluation of their performance, according to [Yuma Consensus](../resources/glossary.md#yuma-consensus). + +The weight matrix is public information, and must be, so that emissions in the Bittensor platform can be transparently fair. However, this transparency makes it possible for subnet validators to free-ride on the work of other validators by copying the latest consensus rather than independently evaluating subnet miners. This is unfair and potentially degrades the quality of validation work, undermining Bittensor's ability to incentivize the best miners and produce the best digital commodities overall. This is known as the **weight copying problem**. + +See [The Weight Copying Problem](./weight-copying-in-bittensor.md). + + +The Commit Reveal feature is designed to solve the **weight copying problem** by hiding weights until they are stale. Copying stale weights should result in validators departing from consensus. + +The Commit Reveal feature uses **[Drand time-lock encryption](https://drand.love/docs/timelock-encryption/)** to automatically reveal validator weights after a concealment period. When a validator sets weights, they are cryptographically encrypted and can only be decrypted after the configured number of tempos has passed. This automation eliminates the need for manual reveals and prevents selective revelation attacks. + +However, it is critical to note that this only works if the consensus weight matrix changes sufficiently on the time scale of the Commit Reveal interval. If the demands on miners are too static, and miner performance is very stable, weight copying will still be successful. The primary solution for this is to demand continuous improvement from miners, requiring them to continuously evolve to maintain their scoring. Combined with a properly tuned Commit Reveal interval, this will keep validators honest, as well as producing the best digital commodities generally. If weights change relatively infrequently (such as once per week), Liquid Alpha 2 can be used to deregister weight copiers. + +## The Commit Reveal Flow + +### Validator Sets Weights + +The sequence of events begins when a validator calls [`set_weights`](pathname:///python-api/html/autoapi/bittensor/core/extrinsics/set_weights/index.html), to commit their ratings of the subnet's miners. Validators do not need to do anything different whether or not Commit Reveal is operating. + +### Automatic Commit with Time-Lock Encryption + +Without Commit Reveal, values are committed openly to the chain. + +With Commit Reveal, the chain automatically: +- Encrypts the weights using **[Drand time-lock encryption](https://drand.love/docs/timelock-encryption/)** +- Commits the encrypted weights to the blockchain via an internal method called [`commit_weights`](pathname:///python-api/html/autoapi/bittensor/core/extrinsics/commit_weights/index.html) +- Calculates the target Drand round based on the current block and `commit_reveal_period` + +The encrypted weights cannot be decrypted by anyone—including the validator who submitted them—until the designated Drand round is reached. + +### Concealment Period + +A waiting interval, specified as a number of tempos, elapses. Subnet owners configure this interval with the `commit_reveal_period` hyperparameter. During this time, the weights remain encrypted on-chain and are therefore not included in Yuma Consensus. + +### Automatic Reveal + +After the `commit_reveal_period` has elapsed, the chain automatically decrypts and reveals the weights at the beginning of the next tempo. This happens when the corresponding Drand beacon pulse becomes available, providing the cryptographic key needed to unlock the time-locked encryption. This use of Drand as the reveal feature gives Commit Reveal a strong cryptographic guarantee. + +### Consensus Processing + +The revealed weights are now publicly visible and input into Yuma Consensus for the next epoch calculation, just as if they had been submitted without Commit Reveal. + + + +The below diagram shows the Commit Reveal process across three tempos. Key things to note: +- **Drand pulse** triggers automatic reveals at block 1005, 1105, 1205 (shortly after each tempo starts) +- **Commit window** is blocks 1090-1099, 1190-1199, 1290-1299 (last 10 blocks of each tempo) +- **Concealment period** protects weights during the tempo +- **Epoch calculation** uses revealed weights at block 1100, 1200, etc. + +
+ +
+ + +## Migrating to Commit Reveal + +### Validators and Miners + +After a subnet owner enables Commit Reveal, validators and miners don't need to change anything. Validators continue calling [`set_weights`](pathname:///python-api/html/autoapi/bittensor/core/extrinsics/set_weights/index.html) as before. All encryption, time-locking, and revealing happens automatically at the chain level. + +### Subnet Owners + +As a subnet owner, you must enable and configure the Commit Reveal feature using two hyperparameters: + +1. **`commit_reveal_weights_enabled`** (boolean) + - Set to `True` to activate Commit Reveal for your subnet + - Default: `False` (disabled) + - When enabled, all validator weights are automatically committed with time-lock encryption + +2. **`commit_reveal_period`** (integer) + - The number of tempos that must elapse before weights are revealed + - Default: `1` (weights revealed after 1 tempo) + - Example: If set to `3`, weights committed in tempo 10 will be revealed at the start of tempo 13 + +See [Setting subnet hyperparameters](../subnets/subnet-hyperparameters.md#set-hyperparameters) for how to update these values. + +#### Commit Reveal and the neuron immunity period + + + +The [Immunity Period](../resources/glossary.md#immunity-period) for neurons is the interval (measured in blocks) during which a neuron (miner or validator) newly registered on a subnet is 'immune' from deregistration due to performance. The duration of this period (in blocks) should always be larger than the Commit Reveal interval (in blocks), otherwise the immunity period will expire before a given miner's scores are available, and they may be deregistered without having their work counted. + +Note: To compare these values, multiply the `commit_reveal_period` by the `tempo` to get the reveal interval in blocks. + +:::danger +Subnet owners must ensure that the miner immunity period (in blocks) is larger than the Commit Reveal interval converted to blocks (commit_reveal_period × tempo). +::: + +When updating the immunity period or Commit Reveal interval hyperparameters for a subnet, use the following formula: + +**Note**: Both values are in blocks after conversion. + +$$ +\begin{align} +\text{new immunity period}_{\text{blocks}} &= (\text{new commit\_reveal\_period}_{\text{tempos}} \times \text{tempo}) \\ +&\quad - (\text{old commit\_reveal\_period}_{\text{tempos}} \times \text{tempo}) \\ +&\quad + \text{old immunity\_period}_{\text{blocks}} +\end{align} +$$ + +Where: +- $\text{tempo}$ is the subnet's tempo hyperparameter (typically 361 blocks per tempo) +- Values are converted to blocks for the calculation +- Both input and output for immunity_period are in blocks +- Both input and output for commit_reveal_period must be multiplied by tempo to convert to blocks + +## Automatic Commit Reveal (added in Commit Reveal 4) + +Previous versions of Commit Reveal required validators to explicitly reveal their committed weights in order to input them to Yuma Consensus. This opened an exploit vector where validators could wait until after other weights are revealed, then decide whether or not to reveal their own previously submitted weights for the tempo based on whether or not it would hurt or help vtrust. + +The Drand-based automatic reveal system prevents that exploit, and more generally provides several important benefits: + +1. **No manual reveals required**: Validators don't need to remember to reveal weights or maintain uptime for reveals +2. **Eliminates selective revelation**: Validators cannot choose not to reveal if they see unfavorable consensus forming +3. **Cryptographic guarantees**: Time-lock encryption ensures weights are revealed on schedule +4. **Reduced transaction costs**: No separate reveal transaction is needed +5. **Trustless operation**: Drand is a decentralized network; no single party controls reveal timing + +
+ +
+ diff --git a/docs/subnets/consensus-based-weights.md b/docs/concepts/consensus-based-weights.md similarity index 83% rename from docs/subnets/consensus-based-weights.md rename to docs/concepts/consensus-based-weights.md index 3e1838df5c..d20056977a 100644 --- a/docs/subnets/consensus-based-weights.md +++ b/docs/concepts/consensus-based-weights.md @@ -4,23 +4,16 @@ title: "Consensus-based Weights/Liquid alpha" # Consensus-based Weights -This guide describes how to use the **consensus-based weights** feature (also called "liquid alpha"). +This guide describes how to use the **consensus-based weights** feature (also called "liquid alpha"). With this feature, a subnet validator's dividends are better correlated to the performance of the subnet miner on which the subnet validator is setting the weights. In this context, see also the documentation for the [Commit Reveal](./commit-reveal.md) feature, as both these features help the subnet validators find new subnet miners that perform well and bond to them quickly. -## Technical paper, blog +## Technical paper, blog, notebooks - See [Amplifying the Weight-copying Penalty in Bittensor, a working paper (PDF)](pathname:///papers/BT-Consensus-based-Weights.pdf). - Blog post: [Consensus-based Weights](https://blog.bittensor.com/consensus-based-weights-1c5bbb4e029b). - Subtensor document section: [Validator bonding](https://github.com/opentensor/subtensor/blob/main/docs/consensus.md#validator-bonding). - -## Collab notebooks - -A subnet owner can run the `weight_copy/liquid_alpha_diagnostic.ipynb` in the Python notebook below to experiment and choose the right values for the hyperparameters `alpha_low`, `alpha_high`, and `commit_reveal_interval`. - -- For commit reveal diagnostic: https://colab.research.google.com/github/opentensor/developer-docs/blob/main/static/weight_copy/commit_reveal_diagnostic.ipynb?authuser=5 -- For liquid alpha diagnostic: https://colab.research.google.com/github/opentensor/developer-docs/blob/main/static/weight_copy/liquid_alpha_diagnostic.ipynb?authuser=5 -- [GitHub directory with Python notebooks](https://github.com/opentensor/developer-docs/tree/main/static/weight_copy/). +- [Python notebooks](https://github.com/latent-to/developer-docs/tree/main/static/weight_copy/). Run the `weight_copy/liquid_alpha_diagnostic.ipynb` to experiment and choose the right values for the hyperparameters `alpha_low`, `alpha_high`, and `commit_reveal_interval`. ## Description @@ -32,21 +25,21 @@ $$ B_{ij}^{(t)} = \alpha\cdot\Delta B_{ij}^{(t)} + (1-\alpha)\cdot B_{ij}^{(t-1)} $$ -This EMA, $B_{ij}^{(t)}$, helps in the early discovery of promising subnet miners and prevents abrupt changes to the bond value. Typically, any abrupt change in the bond value indicates exploitation. +This EMA, $B_{ij}^{(t)}$, helps in the early discovery of promising subnet miners and prevents abrupt changes to the bond value. Typically, any abrupt change in the bond value indicates exploitation. Finally, the **dividend $D_i$ to a subnet validator $i$** is calculated as: $$ D_i = \sum_j B_{ij} \cdot I_j -$$ +$$ -where $B_{ij}$ is the EMA bond value of the subnet validator $i$ with the subnet miner $j$, and $I_j$ is the subnet miner's incentive. See the subtensor document section, [Validator bonding](https://github.com/opentensor/subtensor/blob/main/docs/consensus.md#validator-bonding) for a rigorous mathematical treatment of this topic. +where $B_{ij}$ is the EMA bond value of the subnet validator $i$ with the subnet miner $j$, and $I_j$ is the subnet miner's incentive. See the subtensor document section, [Validator bonding](https://github.com/opentensor/subtensor/blob/main/docs/consensus.md#validator-bonding) for a rigorous mathematical treatment of this topic. ### What changed with this feature Without the consensus-based weights feature, the $\alpha$ in the above equation is set to `0.9`. With the consensus-based weights feature, this $\alpha$ value is made into a variable. An optimum value for the variable $\alpha$ is determined based on the current consensus (YC-2) in a given subnet. Hence, this feature is called **consensus-based weights**. -Using the new subnet hyperparameters that are described below, a subnet owner should experiment and discover the optimum $\alpha$ for their subnet. +Using the new subnet hyperparameters that are described below, a subnet owner should experiment and discover the optimum $\alpha$ for their subnet. ## Installing the consensus-based weights feature @@ -61,7 +54,7 @@ The consensus-based weights feature is available in Bittensor 7.3.0 and later ve Here are summary steps to use the consensus-based weights feature. A subnet owner typically executes these steps: 1. To activate this feature, a subnet owner should set the `liquid_alpha_enabled` (bool) hyperparameter to `True`. -2. Next, the subnet owner should set the upper and lower bounds for $\alpha$ by using a single subnet hyperparameter, `alpha_values` (List[int]). +2. Next, the subnet owner should set the upper and lower bounds for $\alpha$ by using a single subnet hyperparameter, `alpha_values` (List[int]). :::danger Set alpha low and high together You must set `alpha_low` and `alpha_high` together using `alpha_values`. See below. @@ -85,16 +78,17 @@ You must set `alpha_low` and `alpha_high` together using `alpha_values`. See bel ### Value format -When you set the subnet hyperparameters `alpha_low` and `alpha_high`, you must pass their integer equivalents in `u16`. This applies whether you set these hyperparameters using the `btcli` command or in your Python code. These integer values are then converted by the subtensor into their corresponding decimal values in the `u16` format. +When you set the subnet hyperparameters `alpha_low` and `alpha_high`, you must pass their integer equivalents in `u16`. This applies whether you set these hyperparameters using the `btcli` command or in your Python code. These integer values are then converted by the subtensor into their corresponding decimal values in the `u16` format. Use the below conversion formula to determine the integer values for your desired decimal values for both `alpha_low` and `alpha_high` hyperparameters. -$$ +$$ \text{Integer value} = \text{(your-desired-decimal-value)} \times 65535 $$ Hence, for example: -- If you want `alpha_low` to be `0.1`, then you would pass `6554`, which is the rounded up value of `0.1 * 65535`. + +- If you want `alpha_low` to be `0.1`, then you would pass `6554`, which is the rounded up value of `0.1 * 65535`. - If you want `alpha_high` to be `0.8`, then you would pass `52428`, which is the value of `0.8 * 65535`. --- @@ -136,7 +130,7 @@ print(alpha_low_high_result) ### Example Python code -Below is the example Python code showing how to use the above definitions for the commit reveal feature: +Below is the example Python code showing how to use the above definitions for the Commit Reveal feature: ```python import bittensor as bt @@ -168,9 +162,9 @@ print(alpha_low_high_result) ``` :::danger you must always set alpha_low and alpha_high together -You must set the values for both `alpha_low` and `alpha_high` together. Current functionality does not allow setting a value to only one of `alpha_low` or `alpha_high`. +You must set the values for both `alpha_low` and `alpha_high` together. Current functionality does not allow setting a value to only one of `alpha_low` or `alpha_high`. -For example, if you want to set a new value to `alpha_low` but do not want to change the `alpha_high` value, you must pass the new value of `alpha_low`, and also the current, unchanging value of `alpha_high`, while setting the `alpha_values`. +For example, if you want to set a new value to `alpha_low` but do not want to change the `alpha_high` value, you must pass the new value of `alpha_low`, and also the current, unchanging value of `alpha_high`, while setting the `alpha_values`. ::: --- @@ -184,7 +178,7 @@ For example, if you want to set a new value to `alpha_low` but do not want to ch **Syntax** ```bash -btcli sudo set hyperparameters --netuid --param liquid_alpha_enabled --value or +btcli sudo set --netuid --param liquid_alpha_enabled --value or ``` **Example** @@ -192,13 +186,15 @@ btcli sudo set hyperparameters --netuid --param liquid_a For subnet 1 (`netuid` of `1`): ```bash -btcli sudo set hyperparameters --netuid 1 --param liquid_alpha_enabled --value True +btcli sudo set --netuid 1 --param liquid_alpha_enabled --value True ``` + or you can also use, ```bash btcli sudo set ``` + and follow the terminal prompts: ```bash @@ -210,7 +206,7 @@ and follow the terminal prompts: ``` :::info tip -When you use `btcli sudo set` you can use `1` or `0` to enable or disable the `liquid_alpha_enabled` hyperparameter. You can also use `true` or `True`, or `false` or `False`. +When you use `btcli sudo set` you can use `1` or `0` to enable or disable the `liquid_alpha_enabled` hyperparameter. You can also use `true` or `True`, or `false` or `False`. ::: #### 2. Use the `alpha_values` to set the `alpha_low` and `alpha_high` @@ -218,7 +214,7 @@ When you use `btcli sudo set` you can use `1` or `0` to enable or disable the `l **Syntax** ```bash -btcli sudo set hyperparameters --netuid --param alpha_values --value +btcli sudo set --netuid --param alpha_values --value ``` **Example** @@ -226,10 +222,11 @@ btcli sudo set hyperparameters --netuid --param alpha_va Setting the value of `alpha_low` to the decimal `0.1` (integer `6554`) and `alpha_high` to the decimal `0.8` (integer `52428`) for subnet 1 (`netuid` of `1`): ```bash -btcli sudo set hyperparameters --netuid 1 --param alpha_values --value 6554,52429 +btcli sudo set --netuid 1 --param alpha_values --value 6554,52429 ``` Output: + ```bash >> Enter wallet name (default): # >> Enter password to unlock key: # @@ -238,7 +235,7 @@ Output: Now, if you want to only change the `alpha_high` value from `0.8` to `0.85` (integer `55705`), then: -First, execute the `btcli sudo set` command and provide the `netuid`. The terminal will display the current alpha_low` and `alpha_high` values. +First, execute the `btcli sudo set` command and provide the `netuid`. The terminal will display the current alpha_low`and`alpha_high` values. :::warning alert When you use `btcli sudo set,` the display will not show the `alpha_values` parameter. It will only show the `alpha_low` and `alpha_high` parameters. @@ -247,5 +244,5 @@ When you use `btcli sudo set,` the display will not show the `alpha_values` para Use the current value of `alpha_low` from the above display and the new desired value of `alpha_high` and set both like below: ```bash -btcli sudo set hyperparameters --netuid 1 --param alpha_values --value 6554,55706 +btcli sudo set --netuid 1 --param alpha_values --value 6554,55706 ``` diff --git a/docs/root-network.md b/docs/concepts/root-network.md similarity index 70% rename from docs/root-network.md rename to docs/concepts/root-network.md index aed1e399a5..0359579aab 100644 --- a/docs/root-network.md +++ b/docs/concepts/root-network.md @@ -6,16 +6,15 @@ title: "Root Network" :::tip -The Root Network no longer is in operation, so this doc is a kind of historical artifact. The Root Network was decommisioned with the [Dynamic TAO](./dynamic-tao/dtao-guide.md) upgrade in February 2025 +The Root Network no longer is in operation, so this doc is a kind of historical artifact. The Root Network was decommisioned with the [Dynamic TAO](../dynamic-tao/index.md) upgrade in February 2025 ::: - The root network was a special kind of subnet. The root network has the `netuid` of 0. -**Root network validators**: The largest 64 subnet validators, in terms of their stake, from amongst all the subnet validators in all the active subnets in the Bittensor network, were, by default, the validators in the root network. +**Root network validators**: The largest 64 subnet validators, in terms of their stake, from amongst all the subnet validators in all the active subnets in the Bittensor network, were, by default, the validators in the root network. + +**Root network miners**: There were no network miners in the root network. Instead, the subnets take their place. The 64 root network validators set the weights for all these subnets. -**Root network miners**: There were no network miners in the root network. Instead, the subnets take their place. The 64 root network validators set the weights for all these subnets. - -:::tip Root network weights determined emissions -Prior to Dynamic TAO, these root network weights for the subnets determined emissions for the subnets. -::: \ No newline at end of file +:::tip Root network weights determined emissions +Prior to Dynamic TAO, these root network weights for the subnets determined emissions for the subnets. +::: diff --git a/docs/tools.md b/docs/concepts/tools.md similarity index 76% rename from docs/tools.md rename to docs/concepts/tools.md index a83587fb09..d5d8c0a773 100644 --- a/docs/tools.md +++ b/docs/concepts/tools.md @@ -11,36 +11,38 @@ Bittensor provides several tools to help developers, miners, and validators inte ## Bittensor SDK The Bittensor SDK is a Python-based library that allows developers to interact programmatically with the Bittensor network. You can use the SDK to: + - Create and manage wallets - Register miners and validators - Query and monitor network activity - Build applications on top of Bittensor’s decentralized AI infrastructure -**Learn more in the [Bittensor SDK documentation](./bt-api-ref.md)** (link for illustration). +**Learn more in the [Bittensor SDK documentation](../sdk/bt-api-ref.md)** (link for illustration). --- ## Bittensor CLI The Bittensor command-line interface (`btcli`) provides a straightforward way to: + - Create, manage, and encrypt wallet keys - Transfer and stake TAO - Perform subnet management operations (e.g., creating subnets, registering miners/validators) - View wallet information and network status It is designed for users who prefer quick terminal commands or those managing multiple nodes and subnet interactions. -**See [Bittensor CLI reference](./btcli.md)** for detailed usage instructions. +**See [Bittensor CLI reference](../btcli/btcli.md)** for detailed usage instructions. --- ## Wallets and Keys -In Bittensor (like other cryptocurrency applications), a *wallet* is a tool for managing the cryptographic key-pairs required to prove your identity, sign transactions, and access your currency +In Bittensor (like other cryptocurrency applications), a _wallet_ is a tool for managing the cryptographic key-pairs required to prove your identity, sign transactions, and access your currency Bittensor uses a dual-key wallet structure: -- **Coldkey** for secure storage of TAO and high-security operations + +- **Coldkey** for secure storage of TAO and high-security operations - **Hotkey** for operational tasks like validation, mining, and day-to-day transactions Both keys are crucial for safeguarding and participating in the network. -**For a complete guide, see [Wallets & Keys](./getting-started/wallets)** and [Working with Keys](./working-with-keys). - +**For a complete guide, see [Wallets & Keys](../keys/wallets)** and [Working with Keys](../keys/working-with-keys). diff --git a/docs/concepts/weight-copying-in-bittensor.md b/docs/concepts/weight-copying-in-bittensor.md new file mode 100644 index 0000000000..0597fea547 --- /dev/null +++ b/docs/concepts/weight-copying-in-bittensor.md @@ -0,0 +1,100 @@ +--- +title: "The Weight Copying Problem" +--- + + +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + + +# The Weight Copying Problem + +This page explains **weight copying**—a free-riding behavior where validators copy other validators' work instead of independently evaluating miners. This article covers how weight copying works, why it is problematic, and how subnet owners can prevent weight copying on their subnets using Bittensor's [Commit Reveal](./commit-reveal.md) feature. + +See also: +- [Opentensor Weight Copying technical paper (PDF)](pathname:///papers/BT_Weight_Copier-29May2024.pdf) +- [Opentesor Blog: Weight Copying in Bittensor](https://blog.bittensor.com/weight-copying-in-bittensor-422585ab8fa5) + +## What is weight copying? + +In Bittensor subnets, validators are supposed to independently evaluate miners and set weights based on their performance. These weights determine miner emissions through [Yuma Consensus](../learn/yuma-consensus.md). + +**Weight copying** occurs when a validator reads the publicly available weight matrix and copies (or derives from) other validators' weights instead of doing their own evaluation work. This allows them to: +- Avoid the computational cost of evaluation +- Avoid the development cost of building good evaluation systems +- Still earn validator dividends by appearing to participate in consensus + +While this might seem like a minor optimization, it undermines the entire incentive mechanism and can lead to cascading failures in subnet quality. + +
+ +
+ +## The problems with weight copying + +### Degraded subnet quality + +Validators are the quality control mechanism for subnets. When validators copy weights instead of independently evaluating miners: +- Bad miners can persist longer than they should +- Good innovations from new miners take longer to be recognized +- The subnet's ability to produce quality output degrades over time + +### Unfair validator rewards + +Weight copiers earn dividends without doing the work, in a sense free-riding or parasitising validators that actually do perform validation work. In the worst case scenario, this can lead to most validators becoming weight copiers, with real evaluation work being effectively centralized to a small number of honest validators. This would undermine the benefits of distributed consensus as well as being unfair and inefficient. + +If weight copying is more profitable than honest validation, rational actors will copy weights. Another way of thinking about this is that validators must actually pay a cost to validate honestly. Therefore, when weight copying is profitable, the incentive system driving Bittensor is distorted, weakening its ability to fulfill its purpose: producing the best digital commodities in the world. + +Therefore, it can be seen as the subnet owners' responsibility to the community, as well as being in their own interests, to ensure that weight copying is not profitable in their subnets. The best way to do this is by enabling and properly configuring [Commit Reveal](./commit-reveal). + + +Historically, many large weight copiers used an optimized strategy which we can call the stake-weighted averaging attack, that actually gives them *higher* returns than any single honest validator: + +1. Weight copiers wait for weights to be publicly revealed. +2. They compute what weights they can submit that Yuma Consensus will judge as maximally in consensus, by giving the stake-weighted median of validators' weight scores for each miner. See [Glossary: Consensus Score](../resources/glossary#consensus-score). +3. By submitting weights that match the predicted consensus, they maximize their vtrust (validator trust score). +4. Higher vtrust → higher dividends per TAO staked → higher APY. + +This works because in Yuma Consensus, validators are rewarded based on how well their weights align with the emerging consensus. By calculating the stake-weighted median, weight copiers can predict consensus better than any individual honest validator who might have some disagreement with others. As a result, optimized weight copiers achieve higher validator dividends per stake than honest validators, making weight copying more profitable than honest work. + +This is a fundamental incentive problem for Bittensor subnet owners: if validators are needed to do validation work rather than weight copy, the validation work itself must be incentivized more than weight-copying. Fortunately, the Commit Reveal feature exists to make weight copying impossible. + +## How Commit Reveal prevents weight copying + +Bittensor's [Commit Reveal feature](./commit-reveal.md) solves weight copying by introducing a time delay between when weights are set and when they're publicly visible. + +When weights are concealed for one or more tempos, weight copiers only have access to **stale weights** from previous tempos. If miner performance has changed since those old weights were set, the old weights are inaccurate, and copying them will put the copiers far from consensus. This will wreck their vtrust and their emissions, making weight copying unprofitable. + +### The Commit Reveal Flow + +1. Validators set weights +2. Weights are encrypted using time-lock encryption +3. Weights remain hidden for a configured number of tempos (the `commit_reveal_period`) +4. Weights are automatically revealed after the concealment period +5. Revealed weights are then used in Yuma Consensus calculations + + +
+ +
+ + +## The caveat: Dynamic scoring required + +Commit Reveal only prevents weight copying if **miner performance actually changes** over the timescale of the concealment period. If the ground truth about miner rankings is overly static, then even stale weights will be accurate enough to be profitable, and in this case, nothing can prevent weight copying. + +Subnet owners should design subnets that demand continuous miner improvement, which is important generally for producing best-in-class digital commodities, and also ensures that weights from yesterday are less accurate than fresh evaluations today, preventing weight copying. Alternatively, even if weights change infrequently (such as once per week), Liquid Alpha 2 can be used to deregister weight copiers. diff --git a/docs/dynamic-tao/_dtao-btcli.md b/docs/dynamic-tao/_dtao-btcli.md index 08b0cae694..17a42c0b42 100644 --- a/docs/dynamic-tao/_dtao-btcli.md +++ b/docs/dynamic-tao/_dtao-btcli.md @@ -9,7 +9,7 @@ This page documents the command line interface (CLI) for Bittensor with dynamic Access the Dynamic TAO-enabled Bittensor test network at: `wss://rao.chain.opentensor.ai:443/` :::tip Looking for legacy BTCLI doc? -For current/legacy `btcli` doc that supports the `btcli root` commands, see [Bittensor CLI](../btcli.md). +For current/legacy `btcli` doc that supports the `btcli root` commands, see [Bittensor CLI](../btcli.md). ::: **Usage**: @@ -20,20 +20,20 @@ btcli [OPTIONS] COMMAND [ARGS]... **Options**: -* `--version` -* `--install-completion`: Install completion for the current shell. -* `--show-completion`: Show completion for the current shell, to copy it or customize the installation. -* `--help`: Show this message and exit. +- `--version` +- `--install-completion`: Install completion for the current shell. +- `--show-completion`: Show completion for the current shell, to copy it or customize the installation. +- `--help`: Show this message and exit. **Commands**: -* `config`: Config commands, aliases: `c`, `conf` -* `wallet`: Wallet commands, aliases: `wallets`, `w` -* `stake`: Stake commands, alias: `s`, `st` -* `sudo`: Sudo commands, alias: `su` -* `subnet`: Subnet commands, alias: `s`, `subnets` -* `utils`: Utility commands. ??? This seems to work but is not in the `--help` output ??? -* `weights`: Weights commands, aliases: `wt`, `weight` +- `config`: Config commands, aliases: `c`, `conf` +- `wallet`: Wallet commands, aliases: `wallets`, `w` +- `stake`: Stake commands, alias: `s`, `st` +- `sudo`: Sudo commands, alias: `su` +- `subnet`: Subnet commands, alias: `s`, `subnets` +- `utils`: Utility commands. ??? This seems to work but is not in the `--help` output ??? +- `weights`: Weights commands, aliases: `wt`, `weight` ## btcli config @@ -45,7 +45,7 @@ btcli config [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. +- `--help`: Show this message and exit. ### btcli config clear @@ -73,13 +73,13 @@ btcli config clear [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name` -* `-p, --wallet-path, --wallet_path, --wallet.path` -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey` -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint` -* `--cache` -* `--all` -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name` +- `-p, --wallet-path, --wallet_path, --wallet.path` +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey` +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint` +- `--cache` +- `--all` +- `--help`: Show this message and exit. ### btcli config get @@ -93,7 +93,7 @@ btcli config get [OPTIONS] **Options**: -* `--help`: Show this message and exit. +- `--help`: Show this message and exit. ### btcli config metagraph @@ -107,8 +107,8 @@ btcli config metagraph [OPTIONS] **Options**: -* `--reset`: Restore the display of metagraph columns to show all columns. -* `--help`: Show this message and exit. +- `--reset`: Restore the display of metagraph columns to show all columns. +- `--help`: Show this message and exit. ### btcli config set @@ -122,12 +122,12 @@ btcli config set [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--cache, --cache / --no-cache, --no_cache`: Disable caching of some commands. This will disable the `--reuse-last` and `--html` flags on commands such as `subnets metagraph`, `stake show` and `subnets list`. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--cache, --cache / --no-cache, --no_cache`: Disable caching of some commands. This will disable the `--reuse-last` and `--html` flags on commands such as `subnets metagraph`, `stake show` and `subnets list`. +- `--help`: Show this message and exit. ## btcli stake @@ -139,7 +139,7 @@ btcli stake [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. +- `--help`: Show this message and exit. ### btcli stake add @@ -163,22 +163,22 @@ btcli stake add [OPTIONS] **Options**: -* `-a, --all-tokens, --all`: When set, the command stakes all the available TAO from the coldkey. -* `--amount FLOAT`: The amount of TAO to stake [default: 0.0] -* `-m, --max-stake FLOAT`: Stake is sent to a hotkey only until the hotkey's total stake is less than or equal to this maximum staked TAO. If a hotkey already has stake greater than this amount, then stake is not added to this hotkey. [default: 0.0] -* `-in, --include-hotkeys, --hotkey-ss58-address TEXT`: Specifies hotkeys by name or ss58 address to stake to. For example, `-in hk1,hk2` -* `-ex, --exclude-hotkeys TEXT`: Specifies hotkeys by name or ss58 address to not to stake to (use this option only with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` -* `--all-hotkeys / --`no-all-hotkeys``: When set, this command stakes to all hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. [default: `no-all-hotkeys`] -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `-a, --all-tokens, --all`: When set, the command stakes all the available TAO from the coldkey. +- `--amount FLOAT`: The amount of TAO to stake [default: 0.0] +- `-m, --max-stake FLOAT`: Stake is sent to a hotkey only until the hotkey's total stake is less than or equal to this maximum staked TAO. If a hotkey already has stake greater than this amount, then stake is not added to this hotkey. [default: 0.0] +- `-in, --include-hotkeys, --hotkey-ss58-address TEXT`: Specifies hotkeys by name or ss58 address to stake to. For example, `-in hk1,hk2` +- `-ex, --exclude-hotkeys TEXT`: Specifies hotkeys by name or ss58 address to not to stake to (use this option only with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` +- `--all-hotkeys / --`no-all-hotkeys``: When set, this command stakes to all hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. [default: `no-all-hotkeys`] +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli stake child @@ -190,7 +190,7 @@ btcli stake child [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. +- `--help`: Show this message and exit. #### btcli stake child get @@ -212,15 +212,15 @@ btcli stake child get [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet (e.g. 2) -* `--all-netuids, --all, --allnetuids`: When set, gets the child hotkeys from all the subnets. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet (e.g. 2) +- `--all-netuids, --all, --allnetuids`: When set, gets the child hotkeys from all the subnets. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. #### btcli stake child revoke @@ -242,17 +242,17 @@ btcli stake child revoke [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 8) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet, (e.g. 8) +- `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. +- `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] +- `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. #### btcli stake child set @@ -276,19 +276,19 @@ btcli stake child set [OPTIONS] **Options**: -* `-c, --children TEXT`: Enter child hotkeys (ss58) -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `-p, --proportions, --prop FLOAT`: Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `-c, --children TEXT`: Enter child hotkeys (ss58) +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] +- `-p, --proportions, --prop FLOAT`: Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) +- `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] +- `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. #### btcli stake child take @@ -318,20 +318,20 @@ btcli stake child take [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--hotkey TEXT` -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 23) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `-t, --take FLOAT`: Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--hotkey TEXT` +- `--netuid INTEGER`: The netuid of the subnet, (e.g. 23) +- `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. +- `-t, --take FLOAT`: Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. +- `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] +- `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli stake children @@ -343,7 +343,7 @@ btcli stake children [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. +- `--help`: Show this message and exit. #### btcli stake children get @@ -365,15 +365,15 @@ btcli stake children get [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet (e.g. 2) -* `--all-netuids, --all, --allnetuids`: When set, gets the child hotkeys from all the subnets. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet (e.g. 2) +- `--all-netuids, --all, --allnetuids`: When set, gets the child hotkeys from all the subnets. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. #### btcli stake children revoke @@ -395,17 +395,17 @@ btcli stake children revoke [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 8) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet, (e.g. 8) +- `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. +- `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] +- `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. #### btcli stake children set @@ -429,19 +429,19 @@ btcli stake children set [OPTIONS] **Options**: -* `-c, --children TEXT`: Enter child hotkeys (ss58) -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `-p, --proportions, --prop FLOAT`: Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `-c, --children TEXT`: Enter child hotkeys (ss58) +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] +- `-p, --proportions, --prop FLOAT`: Enter the stake weight proportions for the child hotkeys (sum should be less than or equal to 1) +- `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] +- `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. #### btcli stake children take @@ -471,20 +471,20 @@ btcli stake children take [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--hotkey TEXT` -* `--netuid INTEGER`: The netuid of the subnet, (e.g. 23) -* `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. -* `-t, --take FLOAT`: Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. -* `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] -* `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--hotkey TEXT` +- `--netuid INTEGER`: The netuid of the subnet, (e.g. 23) +- `--all-netuids, --all, --allnetuids`: When this flag is used it sets child hotkeys on all the subnets. +- `-t, --take FLOAT`: Use to set the take value for your child hotkey. When not used, the command will fetch the current take value. +- `--wait-for-inclusion / --no-wait-for-inclusion`: If `True`, waits until the transaction is included in a block. [default: wait-for-inclusion] +- `--wait-for-finalization / --no-wait-for-finalization`: If `True`, waits until the transaction is finalized on the blockchain. [default: wait-for-finalization] +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli stake list @@ -498,13 +498,13 @@ btcli stake list [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli stake move @@ -526,17 +526,17 @@ btcli stake move [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--origin-netuid INTEGER`: Origin netuid [required] -* `--destination-netuid INTEGER`: Destination netuid [required] -* `--destination-hotkey TEXT`: Destination hotkey -* `--amount FLOAT`: The amount of TAO to stake [default: 0.0] -* `--stake-all, --all`: Stake all -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--origin-netuid INTEGER`: Origin netuid [required] +- `--destination-netuid INTEGER`: Destination netuid [required] +- `--destination-hotkey TEXT`: Destination hotkey +- `--amount FLOAT`: The amount of TAO to stake [default: 0.0] +- `--stake-all, --all`: Stake all +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--help`: Show this message and exit. ### btcli stake remove @@ -554,7 +554,6 @@ btcli stake remove --amount 100 -in hk1,hk2 This command is for users who wish to reallocate their stake or withdraw them from the network. It allows for flexible management of TAO stake across different neurons (hotkeys) on the network. ::: - **Usage**: ```bash @@ -563,23 +562,23 @@ btcli stake remove [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] -* `--unstake-all, --all`: When set, this command unstakes all staked TAO from the specified hotkeys. -* `-a, --amount FLOAT`: The amount of TAO to unstake. [default: 0.0] -* `--hotkey-ss58-address TEXT`: The ss58 address of the hotkey to unstake from. -* `--keep-stake, --keep FLOAT`: Sets the maximum amount of TAO to remain staked in each hotkey. [default: 0.0] -* `-in, --include-hotkeys TEXT`: Specifies the hotkeys by name or ss58 address to unstake from. For example, `-in hk1,hk2` -* `-ex, --exclude-hotkeys TEXT`: Specifies the hotkeys by name or ss58 address not to unstake from (only use with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` -* `--all-hotkeys / --`no-all-hotkeys``: When set, this command unstakes from all the hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. [default: `no-all-hotkeys`] -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--all-netuids / --no-all-netuids`: Use all netuids [default: no-all-netuids] +- `--unstake-all, --all`: When set, this command unstakes all staked TAO from the specified hotkeys. +- `-a, --amount FLOAT`: The amount of TAO to unstake. [default: 0.0] +- `--hotkey-ss58-address TEXT`: The ss58 address of the hotkey to unstake from. +- `--keep-stake, --keep FLOAT`: Sets the maximum amount of TAO to remain staked in each hotkey. [default: 0.0] +- `-in, --include-hotkeys TEXT`: Specifies the hotkeys by name or ss58 address to unstake from. For example, `-in hk1,hk2` +- `-ex, --exclude-hotkeys TEXT`: Specifies the hotkeys by name or ss58 address not to unstake from (only use with `--all-hotkeys`) i.e. `--all-hotkeys -ex hk3,hk4` +- `--all-hotkeys / --`no-all-hotkeys``: When set, this command unstakes from all the hotkeys associated with the wallet. Do not use if specifying hotkeys in `--include-hotkeys`. [default: `no-all-hotkeys`] +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ## btcli subnet @@ -591,8 +590,7 @@ btcli subnet [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. - +- `--help`: Show this message and exit. ### btcli subnet create @@ -612,14 +610,14 @@ btcli subnet create [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli subnet hyperparameters @@ -641,11 +639,11 @@ btcli subnet hyperparameters [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli subnet list @@ -676,10 +674,10 @@ btcli subnet list [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli subnet lock-cost @@ -701,10 +699,10 @@ btcli subnet lock-cost [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli subnet metagraph @@ -805,7 +803,6 @@ btcli pow_register --netuid 1 --num_processes 4 --cuda This command is suitable for users with adequate computational resources to participate in POW registration. It requires a sound understanding of the network's operations and POW mechanics. Users should ensure their systems meet the necessary hardware and software requirements, particularly when opting for CUDA-based GPU acceleration. ::: - This command may be disabled by the subnet owner. For example, on netuid 1 this is permanently disabled. **Usage**: @@ -816,19 +813,19 @@ btcli subnet pow-register [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--processors INTEGER`: Number of processors to use for POW registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for the next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set the flag to use CUDA for POW registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s), in the order of the device speed (0 is the fastest). [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--processors INTEGER`: Number of processors to use for POW registration. +- `-u, --update-interval INTEGER`: The number of nonces to process before checking for the next block during registration [default: 50000] +- `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] +- `-v, --verbose`: Whether to output the registration statistics verbosely. +- `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set the flag to use CUDA for POW registration. [default: no-use-cuda] +- `-d, --dev-id INTEGER`: Set the CUDA device id(s), in the order of the device speed (0 is the fastest). [default: 0] +- `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] +- `--help`: Show this message and exit. ### btcli subnet register @@ -852,15 +849,15 @@ btcli subnet register [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli subnet show @@ -880,12 +877,12 @@ btcli subnet show [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--help`: Show this message and exit. ## btcli sudo @@ -897,8 +894,7 @@ btcli sudo [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. - +- `--help`: Show this message and exit. ### btcli sudo get @@ -920,11 +916,11 @@ btcli sudo get [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli sudo get-take @@ -933,6 +929,7 @@ Allows users to check their delegate take percentage. This command can be used to fetch the delegate take of your hotkey. #### EXAMPLE + ```bash btcli sudo get-take --wallet-name my_wallet --wallet-hotkey my_hotkey ``` @@ -945,13 +942,13 @@ btcli sudo get-take [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli sudo proposals @@ -960,6 +957,7 @@ View active proposals for the senate in the Bittensor's governance protocol. This command displays the details of ongoing proposals, including proposal hashes, votes, thresholds, and proposal data. #### EXAMPLE + ```bash btcli sudo proposals ``` @@ -972,10 +970,10 @@ btcli sudo proposals [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli sudo senate @@ -984,6 +982,7 @@ Shows the Senate members of the Bittensor's governance protocol. This command lists the delegates involved in the decision-making process of the Bittensor network, showing their names and wallet addresses. This information is crucial for understanding who holds governance roles within the network. #### EXAMPLE + ```bash btcli sudo senate ``` @@ -996,10 +995,10 @@ btcli sudo senate [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli sudo senate-vote @@ -1011,6 +1010,7 @@ USAGE The user must specify the hash of the proposal they want to vote on. The command then allows the Senate member to cast a 'Yes' or 'No' vote, contributing to the decision-making process on the proposal. This command is crucial for Senate members to exercise their voting rights on key proposals. It plays a vital role in the governance and evolution of the Bittensor network. #### EXAMPLE + ```bash btcli sudo senate_vote --proposal ``` @@ -1023,16 +1023,16 @@ btcli sudo senate-vote [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--proposal, --proposal-hash TEXT`: The hash of the proposal to vote on. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--vote-aye / --vote-nay`: The vote casted on the proposal -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--proposal, --proposal-hash TEXT`: The hash of the proposal to vote on. +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--vote-aye / --vote-nay`: The vote casted on the proposal +- `--help`: Show this message and exit. ### btcli sudo set @@ -1054,16 +1054,16 @@ btcli sudo set [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `--param, --parameter TEXT`: The subnet hyperparameter to set -* `--value TEXT`: Value to set the hyperparameter to. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `--param, --parameter TEXT`: The subnet hyperparameter to set +- `--value TEXT`: Value to set the hyperparameter to. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli sudo set-take @@ -1073,6 +1073,7 @@ This command can be used to update the delegate takes. To run the command, the u The command makes sure the new take value is within 0-18% range. #### EXAMPLE + ```bash btcli sudo set-take --wallet-name my_wallet --wallet-hotkey my_hotkey ``` @@ -1085,14 +1086,14 @@ btcli sudo set-take [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--take FLOAT`: The new take value. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--take FLOAT`: The new take value. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ## btcli utils @@ -1104,7 +1105,7 @@ btcli utils [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. +- `--help`: Show this message and exit. ### btcli utils convert @@ -1118,9 +1119,9 @@ btcli utils convert [OPTIONS] **Options**: -* `--rao TEXT`: Convert amount from Rao -* `--tao FLOAT`: Convert amount from Tao -* `--help`: Show this message and exit. +- `--rao TEXT`: Convert amount from Rao +- `--tao FLOAT`: Convert amount from Tao +- `--help`: Show this message and exit. ## btcli wallet @@ -1132,8 +1133,7 @@ btcli wallet [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. - +- `--help`: Show this message and exit. ### btcli wallet balance @@ -1175,15 +1175,15 @@ btcli wallet balance [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `-a, --all`: Whether to display the balances for all the wallets. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. +- `-a, --all`: Whether to display the balances for all the wallets. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet create @@ -1203,7 +1203,6 @@ btcli wallet create --n_words 21 This command is for new users setting up their wallet for the first time, or for those who wish to completely renew their wallet keys. It ensures a fresh start with new keys for secure and effective participation in the Bittensor network. ::: - **Usage**: ```bash @@ -1212,60 +1211,14 @@ btcli wallet create [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words INTEGER` -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. - -### btcli wallet faucet - -Obtain test TAO tokens by performing Proof of Work (PoW). - -This command is useful for users who need test tokens for operations on a local blockchain. - -**IMPORTANT**: THIS COMMAND IS DISABLED ON FINNEY AND TESTNET. - -USAGE - -The command uses the proof-of-work (POW) mechanism to validate the user's effort and rewards them with test TAO tokens. It is -typically used in local blockchain environments where transactions do not use real TAO tokens. - -#### EXAMPLE - -```bash -btcli wallet faucet --faucet.num_processes 4 --faucet.cuda.use_cuda -``` - -:::tip -This command is meant for used in local environments where users can experiment with the blockchain without using real TAO tokens. Users must have the necessary hardware setup, especially when opting for CUDA-based GPU calculations. It is currently disabled on testnet and mainnet (finney). You can only use this command on a local blockchain. -::: - - -**Usage**: - -```bash -btcli wallet faucet [OPTIONS] -``` - -**Options**: - -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--processors INTEGER`: Number of processors to use for proof of work (POW) registration. -* `-u, --update-interval INTEGER`: The number of nonces to process before checking for next block during registration [default: 50000] -* `--output-in-place / --no-output-in-place`: Whether to output the registration statistics in-place. [default: output-in-place] -* `-v, --verbose`: Whether to output the registration statistics verbosely. -* `--use-cuda, --cuda / --no-use-cuda, --no-cuda`: Set flag to use CUDA for proof of work (POW) registration. [default: no-use-cuda] -* `-d, --dev-id INTEGER`: Set the CUDA device id(s) in the order of speed, where 0 is the fastest. [default: 0] -* `-tbp, --threads-per-block INTEGER`: Set the number of threads per block for CUDA. [default: 256] -* `--max-successes INTEGER`: Set the maximum number of times to successfully run the faucet for this command. [default: 3] -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--n-words INTEGER` +- `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet get-identity @@ -1273,7 +1226,7 @@ Shows the identity details of a user's coldkey or hotkey. The command displays the information in a table format showing: -- **Address**: The ``ss58`` address of the queried key. +- **Address**: The `ss58` address of the queried key. - **Item**: Various attributes of the identity such as stake, rank, and trust. @@ -1289,7 +1242,6 @@ btcli wallet get_identity --key This command is primarily used for informational purposes and has no side effects on the blockchain network state. ::: - **Usage**: ```bash @@ -1298,11 +1250,11 @@ btcli wallet get-identity [OPTIONS] **Options**: -* `-k, --key, --ss58 TEXT`: The coldkey or hotkey ss58 address to query. -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `-k, --key, --ss58 TEXT`: The coldkey or hotkey ss58 address to query. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet history @@ -1326,12 +1278,12 @@ btcli wallet history [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet inspect @@ -1417,10 +1369,10 @@ btcli wallet list [OPTIONS] **Options**: -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet new-coldkey @@ -1440,7 +1392,6 @@ btcli wallet new_coldkey --n_words 15 This command is crucial for users who need to create a new coldkey for enhanced security or as part of setting up a new wallet. It is a foundational step in establishing a secure presence on the Bittensor network. ::: - **Usage**: ```bash @@ -1449,14 +1400,14 @@ btcli wallet new-coldkey [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] +- `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet new-hotkey @@ -1477,7 +1428,6 @@ btcli wallet new-hotkey --n_words 24 This command is useful to create additional hotkeys for different purposes, such as running multiple subnet miners or subnet validators or separating operational roles within the Bittensor network. ::: - **Usage**: ```bash @@ -1486,14 +1436,14 @@ btcli wallet new-hotkey [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--n-words, --n_words INTEGER`: The number of words used in the mnemonic. Options: [12, 15, 18, 21, 24] +- `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet overview @@ -1598,12 +1548,10 @@ Users can specify a mnemonic, a seed string, or a JSON file path to regenerate a btcli wallet regen-coldkey --mnemonic "word1 word2 ... word12" ``` - :::tip This command is critical for users who need to regenerate their coldkey either for recovery or for security reasons. ::: - **Usage**: ```bash @@ -1612,17 +1560,17 @@ btcli wallet regen-coldkey [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... +- `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... +- `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. +- `--json-password TEXT`: Password to decrypt the JSON file. +- `--use-password / --no-use-password`: Set this to `True` to protect the generated Bittensor key with a password. [default: use-password] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet regen-coldkeypub @@ -1632,7 +1580,7 @@ Use this command when you need to move machine for subnet mining. Use the public USAGE -The command requires either a public key in hexadecimal format or an ``SS58`` address from the existing coldkeypub.txt from old machine to regenerate the coldkeypub on the new machine. +The command requires either a public key in hexadecimal format or an `SS58` address from the existing coldkeypub.txt from old machine to regenerate the coldkeypub on the new machine. #### EXAMPLE @@ -1644,7 +1592,6 @@ btcli wallet regen_coldkeypub --ss58_address 5DkQ4... This command is particularly useful for users who need to regenerate their coldkeypub, perhaps due to file corruption or loss. You will need either ss58 address or public hex key from your old coldkeypub.txt for the wallet. It is a recovery-focused utility that ensures continued access to your wallet functionalities. ::: - **Usage**: ```bash @@ -1653,14 +1600,14 @@ btcli wallet regen-coldkeypub [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--public-key-hex TEXT`: The public key in hex format. -* `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--public-key-hex TEXT`: The public key in hex format. +- `--ss58, --ss58-address TEXT`: The SS58 address of the coldkey. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet regen-hotkey @@ -1682,7 +1629,6 @@ btcli wallet regen_hotkey --seed 0x1234... This command is essential for users who need to regenerate their hotkey, possibly for security upgrades or key recovery. It should be used with caution to avoid accidental overwriting of existing keys. ::: - **Usage**: ```bash @@ -1691,17 +1637,17 @@ btcli wallet regen-hotkey [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... -* `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... -* `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. -* `--json-password TEXT`: Password to decrypt the JSON file. -* `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--mnemonic TEXT`: Mnemonic used to regenerate your key. For example: horse cart dog ... +- `--seed TEXT`: Seed hex string used to regenerate your key. For example: 0x1234... +- `-j, --json TEXT`: Path to a JSON file containing the encrypted key backup. For example, a JSON file from PolkadotJS. +- `--json-password TEXT`: Password to decrypt the JSON file. +- `--use-password / --no-use-password`: Set to 'True' to protect the generated Bittensor key with a password. [default: no-use-password] +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet set-identity @@ -1711,7 +1657,7 @@ The on-chain identity includes attributes such as display name, legal name, web The command prompts the user for the identity attributes and validates the input size for each attribute. It provides an option to update an existing validator hotkey identity. If the user consents to the transaction cost, the identity is updated on the blockchain. -Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey ``ss58`` address for the identity to be updated. +Each field has a maximum size of 64 bytes. The PGP fingerprint field is an exception and has a maximum size of 20 bytes. The user is prompted to enter the PGP fingerprint as a hex string, which is then converted to bytes. The user is also prompted to enter the coldkey or hotkey `ss58` address for the identity to be updated. If the user does not have a hotkey, the coldkey address is used by default. If setting a validator identity, the hotkey will be used by default. If the user is setting an identity for a subnet, the coldkey will be used by default. @@ -1725,7 +1671,6 @@ btcli wallet set_identity This command should only be used if the user is willing to incur the a recycle fee associated with setting an identity on the blockchain. It is a high-level command that makes changes to the blockchain state and should not be used programmatically as part of other scripts or applications. ::: - **Usage**: ```bash @@ -1734,25 +1679,25 @@ btcli wallet set-identity [OPTIONS] **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--display-name, --display TEXT`: The display name for the identity. -* `--legal-name, --legal TEXT`: The legal name for the identity. -* `--web-url, --web TEXT`: The web URL for the identity. -* `--riot-handle, --riot TEXT`: The Riot handle for the identity. -* `--email TEXT`: The email address for the identity. -* `--pgp-fingerprint, --pgp TEXT`: The PGP fingerprint for the identity. -* `--image-url, --image TEXT`: The image URL for the identity. -* `-i, --info TEXT`: The info for the identity. -* `-x, -𝕏, --twitter-url, --twitter TEXT`: The 𝕏 (Twitter) URL for the identity. -* `--validator / --not-validator`: Are you updating a validator hotkey identity? -* `--netuid INTEGER`: Netuid if you are updating identity of a subnet owner -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--display-name, --display TEXT`: The display name for the identity. +- `--legal-name, --legal TEXT`: The legal name for the identity. +- `--web-url, --web TEXT`: The web URL for the identity. +- `--riot-handle, --riot TEXT`: The Riot handle for the identity. +- `--email TEXT`: The email address for the identity. +- `--pgp-fingerprint, --pgp TEXT`: The PGP fingerprint for the identity. +- `--image-url, --image TEXT`: The image URL for the identity. +- `-i, --info TEXT`: The info for the identity. +- `-x, -𝕏, --twitter-url, --twitter TEXT`: The 𝕏 (Twitter) URL for the identity. +- `--validator / --not-validator`: Are you updating a validator hotkey identity? +- `--netuid INTEGER`: Netuid if you are updating identity of a subnet owner +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--help`: Show this message and exit. ### btcli wallet sign @@ -1780,14 +1725,14 @@ btcli wallet sign [OPTIONS] **Options**: -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--use-hotkey / --no-use-hotkey`: If specified, the message will be signed by the hotkey. If not specified, the user will be prompted. -* `--message TEXT`: The message to encode and sign -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--use-hotkey / --no-use-hotkey`: If specified, the message will be signed by the hotkey. If not specified, the user will be prompted. +- `--message TEXT`: The message to encode and sign +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli wallet swap-hotkey @@ -1817,18 +1762,18 @@ btcli wallet swap-hotkey [OPTIONS] [DESTINATION_HOTKEY_NAME] **Arguments**: -* `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. +- `[DESTINATION_HOTKEY_NAME]`: Destination hotkey name. **Options**: -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] -* `--help`: Show this message and exit. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--prompt, --prompt / -y, --no-prompt, --yes, --no_prompt`: Enable or disable interactive prompts. [default: prompt] +- `--help`: Show this message and exit. ### btcli wallet transfer @@ -1882,8 +1827,7 @@ btcli weights [OPTIONS] COMMAND [ARGS]... **Options**: -* `--help`: Show this message and exit. - +- `--help`: Show this message and exit. ### btcli weights commit @@ -1901,7 +1845,6 @@ btcli wt commit --netuid 1 --uids 1,2,3,4 --w 0.1,0.2,0.3 This command is used to commit weights for a specific subnet and requires the user to have the necessary permissions. ::: - **Usage**: ```bash @@ -1910,17 +1853,17 @@ btcli weights commit [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `-u, --uids TEXT`: UIDs of interest for the specified netuid, e.g. -u 1,2,3 ... -* `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. -* `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163 -s 241 -s 217 ... -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `-u, --uids TEXT`: UIDs of interest for the specified netuid, e.g. -u 1,2,3 ... +- `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. +- `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163 -s 241 -s 217 ... +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. ### btcli weights reveal @@ -1942,14 +1885,14 @@ btcli weights reveal [OPTIONS] **Options**: -* `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. -* `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. -* `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. -* `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet -* `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). -* `-u, --uids TEXT`: Corresponding UIDs for the specified netuid, e.g. -u 1,2,3 ... -* `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. -* `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163,241,217 ... -* `--quiet`: Display only critical information on the console. -* `--verbose`: Enable verbose output. -* `--help`: Show this message and exit. +- `--network, --subtensor.network, --chain, --subtensor.chain_endpoint TEXT`: The subtensor network to connect to. Default: finney. +- `--wallet-name, --name, --wallet_name, --wallet.name TEXT`: Name of the wallet. +- `-p, --wallet-path, --wallet_path, --wallet.path TEXT`: Path where the wallets are located. For example: `/Users/btuser/.bittensor/wallets`. +- `-H, --hotkey, --wallet_hotkey, --wallet-hotkey, --wallet.hotkey TEXT`: Hotkey of the wallet +- `--netuid INTEGER`: The netuid of the subnet in the root network, (e.g. 1). +- `-u, --uids TEXT`: Corresponding UIDs for the specified netuid, e.g. -u 1,2,3 ... +- `-w, --weights TEXT`: Weights for the specified UIDs, e.g. `-w 0.2,0.4,0.1 ...` Must correspond to the order of the UIDs. +- `-s, --salt TEXT`: Corresponding salt for the hash function, e.g. -s 163,241,217 ... +- `--quiet`: Display only critical information on the console. +- `--verbose`: Enable verbose output. +- `--help`: Show this message and exit. diff --git a/docs/dynamic-tao/dtao-faq.md b/docs/dynamic-tao/dtao-faq.md index 0d5bb9f96e..a33a03942a 100644 --- a/docs/dynamic-tao/dtao-faq.md +++ b/docs/dynamic-tao/dtao-faq.md @@ -1,45 +1,15 @@ --- title: "Dynamic TAO FAQ" ---- +--- + import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; -## Timing / Rollout - -### What is the rollout timeline for Dyanmic TAO? What determines the timing? - -Dynamic TAO was introduced by proposal, approved by senate vote, and deployed as an upgrade to Bittensor main network on February 13, 2025 after a year of research, development, and testing. - -Any subsequent modifications require a new proposal to be introduced to a new upgrade following the same process. - -### How will Dynamic TAO take effect? - -The state of the network as far as ledger balances and consensus power will not change immediately upon upgrade; it will occur gradually as subnet specific alpha tokens are emitted and staked into circulation. - -In Dynamic TAO, validator *weight*—a critical score that determines consensus power as well as the allocation of emissions—is determined by a combination of TAO and alpha token holdings. When Dynamic TAO is initiated, there will be no alpha in circulation, so validator's stake weights will be entirely determined by their share of TAO stake. - -But far more alpha than TAO is emitted into circulation every block. As a result, over time there will be more alpha relative to TAO in overall circulation, and the relative weight of a validator in a given subnet will depend more on their alpha stake share relative to their share of the TAO stake on Subnet Zero. - -In order to hasten the process of alpha gaining the majority of stake power in the network, the contribution of TAO stake to validator stake weight is reduced by a global parameter called *TAO weight*. Currently, this is planned to be **18%**, in order to achieve a weight parity between TAO and total alpha in approximately 100 days. - -See [Emissions](../emissions.md) - -
- -
- -
+## General ### Will there be a cap on alpha currency? -Yes. There is a hard cap of 21 million for any subnet's alpha token, the same as for TAO itself. Alpha tokens follow a halving schedule as well. +Yes. There is a hard cap of 21 million for any subnet's alpha token, the same as for TAO itself. Alpha tokens follow a halving schedule as well. At the time of writing, 2 alpha tokens per subnet will be emitted each block, while only 1 TAO is emitted and shared across the whole network. @@ -49,23 +19,23 @@ At the time of writing, 2 alpha tokens per subnet will be emitted each block, wh Instead of staking TAO to a validator, in Dynamic TAO, you stake to a validator on a specific subnet. This can be either a mining subnet (most subnets) or the unique root subnet, a.k.a. Subnet Zero. -- When you stake on a mining subnet, you exchange TAO for a dynamic token, the *alpha* of the subnet on which the validator is working, and stake that into the validator's hotkey. +- When you stake on a mining subnet, you exchange TAO for a dynamic token, the _alpha_ of the subnet on which the validator is working, and stake that into the validator's hotkey. - When you stake on the root subnet, you stake TAO for TAO. Your emissions are TAO. ### What is the risk/reward profile of staking into a subnet? -Each new subnet has its own token, referred to as its alpha. When you stake into a validator within a given subnet, you exchange TAO for that subnet's alpha. When you unstake from the validator in that subnet, you exchange the alpha for TAO. Staking and unstaking is therefore sensitive to the price of the alpha. This price of a subnet's alpha is the ratio of TAO in its reserve to alpha in reserve. +Each new subnet has its own token, referred to as its alpha. When you stake into a validator within a given subnet, you exchange TAO for that subnet's alpha. When you unstake from the validator in that subnet, you exchange the alpha for TAO. Staking and unstaking is therefore sensitive to the price of the alpha. This price of a subnet's alpha is the ratio of TAO in its reserve to alpha in reserve. Staking TAO into a subnet essentially exchanges TAO for that subnet’s alpha token. To exit value, alpha must be exchanged back for TAO at the going rate. Held stake (alpha tokens) may increase or decrease in TAO value as the price of the alpha changes. ### How do emissions to root subnet/Subnet 0 stakers work? - -**Network-wide Impact**: Your stake contributes weight across all subnets where your validator operates. This means your stake extracts emissions from multiple subnets simultaneously. See [Validator stake weight](dtao-guide#validator-stake-weight) for more details. -**Proportional emission and TAO weight**: TAO and alpha are emitted to a validator's stakers in proportion to the validators' holdings in each token. See [Emission in Dynamic TAO: Extraction](../emissions.md#extraction) +**Network-wide Impact**: Your stake contributes weight across all subnets where your validator operates. This means your stake extracts emissions from multiple subnets simultaneously. See [Validator stake weight](../subnets/understanding-subnets.md#validator-stake-weight) for more details. + +**Proportional emission and TAO weight**: TAO and alpha are emitted to a validator's stakers in proportion to the validators' holdings in each token. See [Emission: Extraction](../learn/emissions.md#extraction) ### Can users transfer alpha tokens (subnet tokens)? @@ -81,7 +51,7 @@ Dynamic TAO does not directly change Bittensor's on-chain governance mechanism ( ### Root Subnet/Subnet Zero -In Dynamic TAO, Subnet Zero is a special subnet. It is the only subnet that does not have its own $\alpha$ currency. No miners can register on subnet zero, and no validation work is performed. However validators can register, and $\tau$-holders can stake to those validators, as with any other subnet. This offers a mechanism for $\tau$-holders to stake $\tau$ into validators in a subnet-agnostic way. This works because the weight of a validator in a subnet includes both their share of that subnet's $\alpha$ and their share of staked TAO in Subnet Zero. +Subnet Zero a.k.a. the root subnet is a special subnet. No miners can register on subnet zero, and no validation work is performed. However validators can register, and $\tau$-holders can stake to those validators, as with any other subnet. This offers a mechanism for $\tau$-holders to stake $\tau$ into validators in a subnet-agnostic way. This works because the weight of a validator in a subnet includes both their share of that subnet's $\alpha$ and their share of staked TAO in Subnet Zero. Subnet Zero is sometimes called the root subnet, since it sort of replaces the root network in the pre-Dyanmic-TAO architecture. However, Subnet Zero does not perform consensus over subnets, which was the defining function of the root network. @@ -89,7 +59,6 @@ Subnet Zero is sometimes called the root subnet, since it sort of replaces the r The process of registering a subnet in Dynamic TAO will be very similar to the process of registering a submit previously, except that the cost to register the subnet is now burned, rather than being a lock cost returned to the subnet creator on de-registration. This is because subnets are not deregistered in Dynamic TAO. - ### What is the cost of creating a subnet? Subnet registration cost is dynamic. It doubles when a subnet is registered, and decreases at a slow rate such that the price halves after 38,880 blocks—roughly five and a half days. This implies that, if the demand for new subnets is steady, one should be created roughly every five and a half days. @@ -98,7 +67,7 @@ Subnet registration cost is dynamic. It doubles when a subnet is registered, and Each validator’s weight in the subnet is a function of the alpha staked to them on the subnet, plus the TAO staked to them in Subnet Zero, with the value of the TAO being multiplied by the TAO weight, which is between 0 and 1. -See [validator stake weight](./dtao-guide.md#walidator-stake-weight). +See [validator stake weight](../subnets/understanding-subnets.md#validator-stake-weight). ### What happens when a subnet is abandoned? @@ -112,7 +81,7 @@ Currently, the protocol does not automatically deregister subnets. Abandoned sub **No**. Emissions are calculated by protocol logic (e.g., in `run_coinbase.rs`) and are based on network-wide parameters. Subnet founders cannot arbitrarily print tokens—emission follows the same consistent rules across all subnets. -See [Emissions in Dynamic TAO](../emissions.md) +See [Emissions](../learn/emissions.md) ### What happens to previously locked registration costs from pre-Dynamic-TAO subnets? @@ -130,6 +99,5 @@ Miners/validators may need to watch markets (token prices, volumes) to optimize ## Where can I find more technical details right now? -- Codebase: Refer to the Bittensor codebase, especially `run_coinbase.rs`, which calculates emissions logic for subnets and the root network. +- Codebase: Refer to the Bittensor codebase, especially `run_coinbase.rs`, which calculates emissions logic for subnets and the root network. - The [Dynamic TAO White Paper](https://drive.google.com/file/d/1vkuxOFPJyUyoY6dQzfIWwZm2_XL3AEOx/view) - diff --git a/docs/dynamic-tao/dtao-guide.md b/docs/dynamic-tao/dtao-guide.md deleted file mode 100644 index 6d5a1921e5..0000000000 --- a/docs/dynamic-tao/dtao-guide.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: "Core Dynamic TAO Concepts" ---- - -import ThemedImage from '@theme/ThemedImage'; -import useBaseUrl from '@docusaurus/useBaseUrl'; - -# Core Dynamic TAO Concepts - -Dynamic TAO is a recent evolution of the integrated tokenomic and governance model that underlies the Bittensor network. It represents a significant step in Bittensor's trajectory toward more thorough decentralization, by eliminating the centralized role of the root network in judging the value of subnetworks. Instead, in the Dynamic TAO model, the relative value of subnets is determined in a wholly distributed fashion: by the amount of TAO that users have staked into their currency reserves. - -## Subnet liquidity reserves - -The key mechanism introduced with Dynamic TAO is that each subnet functions as its own automated market marker (AMM), with two liquidity reserves, one containing TAO($$\tau$$)—the currency of the Bittensor network, and one containing a subnet specific "dynamic" currency, referred to as that subnet's alpha ($$\alpha$$) token. The alpha token is purchased by staking TAO into the subnet's reserve, which is initialized with a negligible amount of liquidity (1e-9). - -A subnet's economy therefore consists of three pools of currency: -- **Tao reserves**: the amount of tao ($$\tau$$) that has been staked into the subnet -- **Alpha reserves**: the amount of alpha ($$\alpha$$) available for purchase -- **Alpha outstanding**: the amount of alpha ($$\alpha$$) held in the hotkeys of a subnet's participants, also referred to as the total *stake* in the subnet - -:::tip Terminology: alpha tokens -Each subnet has its own currency with its own name, but in the abstract a given subnet's token is referred to as its $\alpha$ token. With a set of subnets in mind, we refer to $\alpha$ as the token for subnet $\alpha$, $$\beta$$ as the token for subnet $$\beta$$, $$\gamma$$ as the token for subnet $$\gamma$$, and so on. - -These subnet tokens contrast with TAO ($$\tau$$), the token of the Bittensor network as a whole. A subnet pool's reserve ratio (tao/alpha) determines the price of its alpha token. -::: -The *price* of a subnet's alpha token is determined by the ratio of TAO in that subnet's reserve to its alpha in reserve. Alpha currency that is not held in reserve but is which is held in the hotkeys of subnet participants is referred to as *alpha outstanding*. - -Run `btcli subnet list` with the Dynamic TAO-enabled `btcli` to view information about the subnets and their currency reserves on Bittensor testnet. - -```txt - ┃ ┃ Price ┃ Market Cap ┃ ┃ ┃ ┃ ┃ - Netuid ┃ Name ┃ (τ_in/α_in) ┃ (α * Price) ┃ Emission (τ) ┃ P (τ_in, α_in) ┃ Stake (α_out) ┃ Supply (α) ┃ Tempo (k/n) -━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━ - 0 │ τ root │ 1.00 τ/Τ │ τ 5.93m │ τ 0.0000 │ -, - │ Τ 5.93m │ 5.93m Τ /21M │ -/- - 3 │ γ templar │ 0.02 τ/γ │ τ 57.32 │ τ 0.0197 │ τ 31.44, 1.43k γ │ 1.18k γ │ 2.61k γ /21M │ 67/99 - 9 │ ι pretrain │ 0.02 τ/ι │ τ 55.38 │ τ 0.0194 │ τ 30.91, 1.46k ι │ 1.16k ι │ 2.61k ι /21M │ 73/99 - 1 │ α apex │ 0.02 τ/α │ τ 54.45 │ τ 0.0192 │ τ 30.65, 1.47k α │ 1.14k α │ 2.61k α /21M │ 65/99 - 2 │ β omron │ 0.02 τ/β │ τ 54.45 │ τ 0.0192 │ τ 30.65, 1.47k β │ 1.14k β │ 2.61k β /21M │ 66/99 - 4 │ δ targon │ 0.02 τ/δ │ τ 54.45 │ τ 0.0192 │ τ 30.65, 1.47k δ │ 1.14k δ │ 2.61k δ /21M │ 68/99 - ... -``` -See: [Using Dynamic TAO](./index.md#using-dynamic-tao) - -## Price/rate of alpha tokens - -### Ideal price -For each subnet, you'll see that *Price* (listed in the third column) is a function of TAO in reserve `τ_in` over alpha in reserve `α_in` - -$$ -Price = \frac{\tau_{in}}{\alpha_{in}} -$$ - -For example, if for subnet $\varepsilon$, its subnet pool contains TAO reserves of 1000 TAO units and its alpha reserves of 16000 $\varepsilon$ units, then the relative price of the $\varepsilon$ token is: - -$$ -R = \frac{\tau_{in}}{\alpha_{in}} = \frac{1000}{16000} = 0.0625 -$$ - -Hence, -$$ -\text{1 } \varepsilon = 0.0625 \text{ TAO} -$$ - -This exchange rate can change every block when staking or unstaking or emissions occur on this subnet. - -## Emission in Dynamic TAO - -Liquidity is steadily emitted into the Bittensor token economy according to an algorithm intended to foster growth while stabilizing prices and protecting them from manipulation. - -Each block: -- the chain emits TAO and injects it into the TAO reserves of the subnets. - -- the chain emits alpha tokens at twice the base alpha emission rate (which starts at 1 α/block and follows the same halving schedule as TAO). These emitted alpha tokens are allocoated between: - - the subnet's alpha reserve (increasing available liquidity) - - alpha outstanding (incentives for miners, validators, and subnet creators) - -See the main article: [Emissions](../emissions) - -## Decentralized evaluation of subnets - -The relative value or *weight* of subnets within Bittensor is critically important as it determines emissions to different subnets and their participant miners and validators. Prior to Dynamic TAO, relative weight among subnets within the Bittensor network is determined by Yuma Consensus over the evaluations of the Root Network validators. This gives a fundamentally centralizing role to the holders of Root Network validator keys. - -In Dynamic TAO, the relative weight is determined organically according to the emergent market value of the subnet, as represented by its stabilized token price. TAO-holders can stake TAO into subnets in exchange for the subnet-specific dynamic currency, referred to as the subnet's alpha ($$\alpha$$) token. In this way, stakers 'vote with their TAO' for the value of the subnet, determining the emissions to the validators and miners working in it. In return, stakers extract a share of the subnet's emissions. - -## Subnet Zero - -In Dynamic TAO, Subnet Zero—or *Root Subnet*—is a special subnet. It is the only subnet that does not have its own $\alpha$ currency. No miners can register on subnet zero, and no validation work is performed. However validators can register, and $\tau$-holders can stake to those validators, as with any other subnet. This offers a mechanism for $\tau$-holders to stake $\tau$ into validators in a subnet-agnostic way. This works because the weight of a validator in a subnet includes both their share of that subnet's $\alpha$ and their share of TAO staked into the root subnet. in Subnet Zero. - -Over time, the emissions generated by TAO staked into Subnet Zero will decrease, relative to stake held in the alpha currency of active subnets. See [Note on evolution of Bittensor token economy](../emissions#note-on-evolution-of-bittensor-token-economy). - -## Validator stake weight - -A validator's stake weight in a subnet equals their alpha stake plus their TAO stake times the `tao_weight` parameter: - -$$ - -\text{Validator stake weight} = \text{Alpha stake} (\alpha) + \text{TAO stake} (\tau) \times \text{TAO weight} - -$$ -:::tip -A validator's stake weight in Subnet Zero is simply their staked TAO. -::: - -A validator's relative stake weight (their stake weight over the total stake weight) in a subnet determines their voting power when evaluating miners, and determines their share of emissions. - -$$ - -\text{Validator x's relative stake weight} -= \frac{\alpha_x + \tau_x \times w_{\tau}} - {\displaystyle \sum_{v \in \text{validators}} - \bigl(\alpha_v + \tau_v \times w_{\tau}\bigr)} - -$$ - diff --git a/docs/dynamic-tao/index.md b/docs/dynamic-tao/index.md index ecc2c39d9d..3122163c48 100644 --- a/docs/dynamic-tao/index.md +++ b/docs/dynamic-tao/index.md @@ -13,8 +13,6 @@ It was introduced by proposal, approved by senate vote, and introduced as an upg See the [Dynamic TAO White Paper](https://drive.google.com/file/d/1vkuxOFPJyUyoY6dQzfIWwZm2_XL3AEOx/view) for a full explanation. -See: [Conceptual guide to Dynamic TAO](./dtao-guide.md) - ## What to expect with Dynamic TAO Most operations will remain unchanged, including the main workflows for miners (e.g., registering on subnets) and validators (e.g., setting weights on miners). @@ -31,10 +29,10 @@ The changes to `btcli` and the Bittensor SDK are not backwards compatible. To use Dynamic TAO, make sure you upgrade to the most recent stable versions of the Bittensor SDK and `btcli`. See: + - [Bittensor SDK release page](https://pypi.org/project/bittensor/) - [Bittensor CLI release page](https://pypi.org/project/bittensor-cli/) -- [Upgrade the Bittensor SDK](../getting-started/installation.md#upgrade) - +- [Upgrade the Bittensor SDK](../getting-started/installation.md#upgrade-the-bittensor-sdk) ### Subnet tokens/liquidity pools @@ -42,7 +40,8 @@ The most visible difference introduced with Dynamic TAO is the addition of one n Run `btcli subnet list` to view information about the subnets and their currency reserves: -For example: +For example: + ```txt Subnets Network: rao @@ -60,6 +59,6 @@ For example: ... ``` -### Gradual impact on consensus dynamics +### Gradual impact on consensus dynamics -The rollout of Dynamic TAO is calculated to have a gradual impact. When Dynamic TAO is first released, the weight of all validators (in terms of stake) will remain unchanged, because a biasing variable known as *TAO weight*, which controls the relative weight of TAO and alpha currencies, will heavily favor TAO—which currently has 100% weight since alpha currencies don't exist. Over time (an estimated 100 days), this *TAO Weight* will shift to favor alpha currencies over TAO. +The rollout of Dynamic TAO is calculated to have a gradual impact. When Dynamic TAO is first released, the weight of all validators (in terms of stake) will remain unchanged, because a biasing variable known as _TAO weight_, which controls the relative weight of TAO and alpha currencies, will heavily favor TAO—which currently has 100% weight since alpha currencies don't exist. Over time (an estimated 100 days), this _TAO Weight_ will shift to favor alpha currencies over TAO. diff --git a/docs/dynamic-tao/sdk-cheat-sheet.md b/docs/dynamic-tao/sdk-cheat-sheet.md index 152301fa4b..e9f1605a65 100644 --- a/docs/dynamic-tao/sdk-cheat-sheet.md +++ b/docs/dynamic-tao/sdk-cheat-sheet.md @@ -2,8 +2,7 @@ title: "Dynamic TAO SDK Cheat Sheet" --- -This page provides a quick reference for the core functionalities for the Bittensor Python SDK that have changed for [Dynamic TAO](./index.md), and some example scripts to demonstrate functionality such as [viewing exchange rates](#example-viewing-exchange-rates) and [staking and unstaking](#example-staking-and-unstaking) into subnets. - +This page provides a quick reference for the core functionalities for the Bittensor Python SDK that have changed for [Dynamic TAO](./index.md), and some example scripts to demonstrate functionality such as [viewing exchange rates](#display-current-exchange-rates) and [manage staking and unstaking](#managing-stake) into subnets. Updates to the `subtensor` and `async_subtensor` modules and the `DynamicInfo` class provide new ways to view information related to new Dynamic TAO features, such as alpha token prices, token reserve amounts, and wallet balances. Functionality around staking and unstaking has been updated to reflect the new nature of staking/unstaking in Dynamic TAO. @@ -43,7 +42,6 @@ Or the following configuration for synchronous calls to Bittensor test network: sub = bt.Subtensor(network="test") ``` - ## The `DynamicInfo` object The state of a subnet, with all of the new attributes, is encapsulated in a `DynamicInfo` object. This is what is returned by the `subnet` and `all_subnets` methods. @@ -75,10 +73,13 @@ class DynamicInfo: subnet_identity: Optional[SubnetIdentity] ``` + ## Viewing subnets + Subnets evolve substantially in Dynamic TAO! Each subnet has its own currency, known as its alpha token, and an internal economy comprising a currency reserve of TAO, a reserve of its own alpha token, and a ledger of staked balances, to keep track of all of its stakers—those who have put TAO into its reserve in exchange for alpha. #### `all_subnets` + ```python all_subnets( block_number: Optional[int] = None @@ -91,88 +92,99 @@ Description: Fetches information about all subnets at a certain block height (or Returns: A list of DynamicInfo objects (detailed below). #### `subnet` + ```python subnet( - netuid: int, + netuid: int, block_number: Optional[int] = None ) -> DynamicInfo ``` + Fetches information about a single subnet identified by netuid. Returns a DynamicInfo object describing the subnet’s current state. - #### `metagraph` + ```python metagraph( - netuid: int, + netuid: int, block: Optional[int] = None ) -> bittensor.Metagraph ``` - Returns the metagraph for a specified subnet netuid. The metagraph includes detailed data on the neurons in the subnet. ## Exchange rates + You can query the DynamicInfo object for the exchange rates between TAO and alpha tokens. You can use `all_subnets` or `subnet` to get the DynamicInfo object. ```python subnet = sub.subnet(netuid=1) ``` + ### Calculate exhange rates + #### `tao_to_alpha` ```python tao_to_alpha(self, tao: Union[Balance, float, int]) -> Balance: ``` -Description: Returns an 'ideal' estimate of how much Alpha a staker would receive at the current price, *ignoring slippage*. + +Description: Returns an 'ideal' estimate of how much Alpha a staker would receive at the current price, _ignoring slippage_. Parameters: - `tao`: Amount of TAO to stake. +`tao`: Amount of TAO to stake. #### `alpha_to_tao` + ```python alpha_to_tao(self, alpha: Union[Balance, float, int]) -> Balance: ``` -Description: Returns an 'ideal' estimate of how much TAO would be yielded by unstaking at the current price, *ignoring slippage*. + +Description: Returns an 'ideal' estimate of how much TAO would be yielded by unstaking at the current price, _ignoring slippage_. Parameters: - `alpha`: Amount of Alpha to unstake. +`alpha`: Amount of Alpha to unstake. #### `tao_to_alpha_with_slippage` + ```python tao_to_alpha_with_slippage(tao: Union[Balance, float, int], percentage: bool = False) -> Union[tuple[Balance, Balance], float]: ``` + Returns an estimate of how much Alpha would a staker receive if they stake their TAO using the current pool state. Parameters: - `tao`: Amount of TAO to stake. - `percentage`: If True, returns the percentage difference between the estimated amount and ideal amount as if there was no slippage. +`tao`: Amount of TAO to stake. +`percentage`: If True, returns the percentage difference between the estimated amount and ideal amount as if there was no slippage. Returns: - Tuple of balances where the first part is the amount of Alpha received, and the - second part (slippage) is the difference between the estimated amount and ideal - amount as if there was no slippage - OR - Percentage of the slippage as a float +Tuple of balances where the first part is the amount of Alpha received, and the +second part (slippage) is the difference between the estimated amount and ideal +amount as if there was no slippage +OR +Percentage of the slippage as a float #### `alpha_to_tao_with_slippage` + ```python alpha_to_tao_with_slippage(alpha: Union[Balance, float, int], percentage: bool = False) -> Union[tuple[Balance, Balance], float]: ``` + Returns an estimate of how much TAO would a staker receive if they unstake their alpha using the current pool state. Parameters: - `alpha`: Amount of Alpha to unstake. - `percentage`: If True, returns the percentage difference between the estimated amount and ideal amount as if there was no slippage. +`alpha`: Amount of Alpha to unstake. +`percentage`: If True, returns the percentage difference between the estimated amount and ideal amount as if there was no slippage. Returns: - Tuple of balances where the first part is the amount of TAO received, and the - second part (slippage) is the difference between the estimated amount and ideal - amount as if there was no slippage - OR - Percentage of the slippage as a float +Tuple of balances where the first part is the amount of TAO received, and the +second part (slippage) is the difference between the estimated amount and ideal +amount as if there was no slippage +OR +Percentage of the slippage as a float ### Display current exchange rates @@ -197,10 +209,11 @@ print("alpha_to_tao", subnet.alpha_to_tao(100)) ## Managing stake #### `get_stake` + ```python get_stake( - hotkey_ss58: str, - coldkey_ss58: str, + hotkey_ss58: str, + coldkey_ss58: str, netuid: int ) -> bittensor.Balance @@ -208,36 +221,38 @@ get_stake( Description: Retrieves the staked balance for a given (hotkey, coldkey) pair on a specific subnet. Returns a `bittensor.Balance` object with the staked amount. Parameters: + - hotkey_ss58: Hotkey SS58 address. - coldkey_ss58: Coldkey SS58 address (owner). - netuid: Unique ID of the subnet. - - #### `add_stake` ```python async add_stake( - wallet, - hotkey: str, - netuid: int, + wallet, + hotkey: str, + netuid: int, tao_amount: Union[float, bittensor.Balance, int] ) ``` + Description: Adds (stakes) an amount of TAO (tao_amount) to a specific subnet (netuid) under the provided hotkey. Parameters: + - wallet: Your Bittensor wallet object. - hotkey: The SS58 address (hotkey) to be staked. - netuid: Unique ID of the subnet on which you want to stake. - tao_amount: Amount to stake, can be a float, integer, or bittensor.Balance object. #### `unstake` + ```python unstake( - wallet, - hotkey: str, - netuid: int, + wallet, + hotkey: str, + netuid: int, amount: Union[float, bittensor.Balance, int] ) @@ -246,16 +261,17 @@ unstake( Description: Unstakes amount of TAO from the specified hotkey on a given netuid. Parameters: + - wallet: Your Bittensor wallet object. - hotkey: The SS58 address (hotkey) from which you want to remove stake. - netuid: Unique ID of the subnet. - amount: Amount to unstake. - #### `get_balance` + ```python get_balance( - address: str, + address: str, block: Optional[int] = None ) -> bittensor.Balance @@ -264,32 +280,38 @@ get_balance( Description: Returns the current (or specified block’s) coldkey TAO balance for an address. Parameters: + - address: SS58 address to check. - block: Optional block number at which to fetch the balance. Uses the latest block if None. - #### `get_current_block` + ```python get_current_block() -> int ``` + Description: Returns the current chain block number. + #### `wait_for_block` + ```python wait_for_block( block: Optional[int] = None ) ``` + Description: Waits for the next block to arrive or waits until a specified block number is reached if provided. Update: we have added proper nonce protection allowing you to run gather operations on stake/unstake/transfers, such as: + ```python scatter_stake = await asyncio.gather(*[ sub.add_stake( hotkey, coldkey, netuid, amount ) for netuid in range(64) ] ) ``` - ### Staking + The following script incrementally stakes 3 TAO into several subnets over many blocks: ```python @@ -308,11 +330,11 @@ while total_spend < 3: for netuid in to_buy: subnet = sub.subnet(netuid) print(f"slippage for subnet {netuid}", subnet.slippage(increment)) - sub.add_stake( - wallet = wallet, - netuid = netuid, - hotkey = subnet.owner_hotkey, - tao_amount = increment, + sub.add_stake( + wallet = wallet, + netuid = netuid, + hotkey = subnet.owner_hotkey, + tao_amount = increment, ) current_stake = sub.get_stake( @@ -325,6 +347,7 @@ while total_spend < 3: print (f'netuid {netuid} price {subnet.price} stake {current_stake}') sub.wait_for_block() ``` + ```console Enter your password: Decrypting... @@ -345,6 +368,7 @@ netuid 5 price τ0.001784484 stake ε11.208213619 ... ``` + ### Unstaking The below script will reverse the effects of the above, by incrementally unstaking alpha tokens from the list of subnets to yield TAO. @@ -366,11 +390,11 @@ while total_sell < 3: subnet = sub.subnet(netuid) print(f"slippage for subnet {netuid}", subnet.alpha_slippage(increment)) - sub.remove_stake( - wallet = wallet, - netuid = netuid, - hotkey = subnet.owner_hotkey, - amount = increment, + sub.remove_stake( + wallet = wallet, + netuid = netuid, + hotkey = subnet.owner_hotkey, + amount = increment, ) current_stake = sub.get_stake( coldkey_ss58 = wallet.coldkeypub.ss58_address, @@ -382,6 +406,7 @@ while total_sell < 3: print (f'netuid {netuid} price {subnet.price} stake {current_stake}') sub.wait_for_block() ``` + ```console Enter your password: Decrypting... @@ -410,23 +435,27 @@ netuid 5 price τ0.001785179 stake ε33.619312896 You can register your hotkey on a subnet using the `burned_register` method. This is necessary for staking, mining or validating. #### `burned_register` + ```python burned_register( - wallet, - netuid: int, + wallet, + netuid: int, ) -> bool ``` Description: Registers a hotkey on a subnet. Parameters: + - wallet: Your Bittensor wallet object. - netuid: Unique ID of the subnet. Returns: + - bool: True if the registration was successful, False otherwise. Sample script: + ```python import bittensor as bt logging = bt.logging @@ -440,13 +469,13 @@ wallet.unlock_coldkey() reg = sub.burned_register(wallet=wallet, netuid=3) ``` - ### View registered subnets #### `get_netuids_for_hotkey` + ```python get_netuids_for_hotkey( - hotkey: str, + hotkey: str, ) -> list[int] ``` @@ -454,9 +483,11 @@ get_netuids_for_hotkey( Description: Returns the netuids in which a hotkey is registered. Parameters: + - hotkey: SS58 address to check. Example usage: + ```python import bittensor as bt sub = bt.Subtensor(network="test") @@ -470,10 +501,10 @@ print(netuids) ``` #### `btcli wallet overview` + You can also use the `btcli` to check subnet registrations using `btcli wallet overview`. This displays the registrations to subnets by hotkeys controlled by the wallet: - ```shell Wallet @@ -505,14 +536,13 @@ Subnet: 119: vidac Ⲃ ``` - ## View a hotkey's emissions This script displays the last day's emissions for a specified hotkey on all subnets on which the hotkey is registered. This could be useful for a miner to see how much they've been extracting from the different subnets, if they've been mining on several. -Be aware that daily emissions can fluctuate widely. See [Emissions](../emissions.md). +Be aware that daily emissions can fluctuate widely. See [Emissions](../learn/emissions.md). ```python from bittensor.core.async_subtensor import AsyncSubtensor @@ -534,7 +564,7 @@ async def main(): all_sn_dynamic_info = {info.netuid: info for info in all_sn_dynamic_info_list} daily_blocks = (60 * 60 * 24) / BLOCKTIME # Number of blocks per day - + print(f"Hotkey: {HOTKEY}") @@ -542,10 +572,10 @@ async def main(): metagraphs = await asyncio.gather(*[ subtensor.metagraph(netuid=id) for id in NETUIDS]) for id in NETUIDS: print(f"UID: {id}") - + metagraph = metagraphs[id] tempo_multiplier = daily_blocks / metagraph.tempo - + subnet_info = all_sn_dynamic_info.get(id) uid = metagraph.hotkeys.index(HOTKEY) if HOTKEY in metagraph.hotkeys else None @@ -565,4 +595,4 @@ async def main(): asyncio.run(main()) -``` \ No newline at end of file +``` diff --git a/docs/dynamic-tao/staking-unstaking-dtao.md b/docs/dynamic-tao/staking-unstaking-dtao.md deleted file mode 100644 index dc9b632b54..0000000000 --- a/docs/dynamic-tao/staking-unstaking-dtao.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "Understanding Pricing and Anticipating Slippage" ---- - -# Understanding Pricing and Anticipating Slippage - -Each Bittensor subnet operates as a *constant product AMM*, meaning that it will accept trades that conserve the product of the quantities of the two tokens in reserve, TAO and alpha. To calulate the price in one token of batch of the other token that a buyer wishes to acquire—alpha if they are staking, or TAO if they are unstaking—the algorithm assumes that the transaction does not change this product, so the product of TAO and alpha is the same before and after. - -When staking, the product K of TAO in reserve and alpha in reserve is the same before and after the transaction, so the initial product must be equal to the product after the cost in TAO is added to the reserve, and the stake is removed from the reserve and placed in the staked hotkey: - -$$ -\tau_{\mathrm{in}} \,\alpha_{\mathrm{in}} = k -$$ -$$ -(\tau_{\mathrm{in}} + \text{cost}) \bigl(\alpha_{\mathrm{in}} - \text{stake}\bigr) = k -$$ -$$ -(\tau_{\mathrm{in}} + \text{cost}) \bigl(\alpha_{\mathrm{in}} - \text{stake}\bigr) - = \tau_{\mathrm{in}} \,\alpha_{\mathrm{in}} -$$ - - -This means that if we choose to stake in a certain amount of TAO (if we specify the cost), then the yielded stake (the quantity of alpha to be removed from reserve and granted to the staked hotkey) is: - -$$ -\text{Stake} = \alpha_{\text{in}} - \frac{\tau_{\text{in}} \alpha_{\text{in}}} {\tau_{\text{in}} + \text{cost}} - -$$ - -For example, suppose that a subnet has 100 alpha in reserve and 10 TAO, and we want to stake in 5 TAO. - -The price at this moment is 10 TAO / 100 alpha, or 10 alpha per TAO, so if we stake 5 TAO, we would expect 50 alpha, without taking slippage into account. - -With slippage, the yielded alpha stake will be: - -$$ -\text{Stake} = 100 - \frac{ 10 * 100} {10 + 5} - -$$ - -or 33.333 alpha sent to the hotkey. So in this case, the slippage is the difference between the ideal expectation of 50 and the actual swap value of 33.33333: -$$ -16.667 = 50 - 33.333 -$$ - -This slippage is 50% of the actual swap value, which is extremely high, because we chose small values for the available liquidity. In general, slippage is high when available liquidity is limited compared to the magnitude of the transaction, since the transaction itself is changing the price significantly. - -:::tip -`btcli` shows the slippage of staking and unstaking operations, so you don't need to calculate it yourself. See [Stake into a node](#stake-into-a-node). -::: - diff --git a/docs/emissions.md b/docs/emissions.md deleted file mode 100644 index 508e00c93d..0000000000 --- a/docs/emissions.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: "Emission" ---- - -import ThemedImage from '@theme/ThemedImage'; -import useBaseUrl from '@docusaurus/useBaseUrl'; - -# Emission - -Emission is the process by which the Bittensor network allocates TAO and alpha to participants, including miners, validators, stakers, and subnet creators. - -It unfolds in two stages: - -- Injection into subnets -- Extraction by participants - -See the [Dynamic TAO White Paper](https://drive.google.com/file/d/1vkuxOFPJyUyoY6dQzfIWwZm2_XL3AEOx/view) for a full explanation. - -### Injection - -The first stage of emissions is *injection of liquidity* into the subnet pools. Liquidity is injected to each subnet in proportion to the price of its token compared to the price of other subnet tokens. This is designed to incentivize development on the most valuable subnets. - -Each block: - -- TAO is injected into the subnet's **TAO reserve**. -- Alpha is injected into the subnet's **alpha reserve**. -- Alpha is allocated to *alpha outstanding*, to be extracted by participants. - -#### TAO reserve injection - -A subnet's TAO reserve injection is computed in proportion to the price of its alpha token over the sum of prices for all the subnets in Bittensor. - -Given set $\mathbb{S}$ of all subnets, and a total per block TAO emission $\Delta\bar{\tau}$, which begins at 1 TAO and follows a halving schedule, TAO emission $\Delta\tau_i$ to subnet $i$ with price $p_i$ is: - -$$ -\Delta\tau_i = \Delta\bar{\tau} \times -\frac - {p_i} - {\sum_{j \in \mathbb{S}} -\bigl(p_j)} -$$ - -#### Alpha reserve injection - -Alpha is then injected in proportion to the price of the token, so that growth of a subnet's liquidity pools does not not change the price of the alpha token. - -Recall that token price for a subnet is its TAO in reserve divided by its alpha reserve: - -$$ -p_i = \frac - {\tau_i} - {\alpha_i} -$$ - -So in order to inject alpha without changing the price, it should follow: - -$$ -\Delta\alpha_i = \frac - {\Delta\tau_i} - {p_i} -$$ - -When we fill in this equation with the previous formula for $\Delta\tau_i$, the price $p_i$ is cancelled out of the equation, yielding: - -$$ -\Delta\alpha_i = - \frac - {\Delta\bar{\tau}} - {\sum_{j \in \mathbb{S}} - \bigl(p_j)} -$$ - - -However, alpha injection is also capped at 1 by the algorithm, to prevent runaway inflation. Therefore, with cap or *alpha emission rate* $\Delta\bar{\alpha_i}$, emission $\Delta\alpha_i$ to subnet $i$ is: - -$$ -\Delta\alpha_i = \min\left\{ - \frac - {\Delta\bar{\tau}} - {\sum_{j \in \mathbb{S}} - \bigl(p_j)}, - \Delta\bar{\alpha_i} \right\} - -$$ - -The cap or *alpha emission rate* $\Delta\bar{\alpha_i}$ for subnet $i$, starts at 1 and follows a halving schedule identical to that of TAO, beginning when subnet $i$ is created. - -#### Alpha outstanding injection - -Each block, liquidity is also set aside to be emitted to participants (validators, miners, stakers, and subnet creator). The quantity per block is equal to the *alpha emission rate* $\Delta\bar{\alpha_i}$ for subnet $i$. - -### Extraction - -At the end of each tempo (360 blocks), the quantity of alpha accumulated over each block of the tempo is extracted by network participants in the following proportions: - -1. 18% by subnet owner -1. 41% of emissions go to miners. The allocation to particular miners is determined by [Yuma Consensus: Miner emissions#miner-emissions](./yuma-consensus). -1. 41% by validators and their stakers. - 1. First, the allocation to validators miners is determined by [Yuma Consensus: Validator Emissions](./yuma-consensus#validator-emissions). - 1. Then, validators extract their take from that allocation. - 1. Then, TAO and alpha are emitted to stakers in proportion to the validators' holdings in each token. TAO emissions are sourced by swapping a portion of alpha emissions to TAO through the subnet's liquidity pool. - - For validator x's TAO stake $\tau_x$, and alpha stake $\alpha_x$, and the global TAO weight $w_{\tau}$: - - - TAO is emitted to stakers on the root subnet (i.e. stakers in TAO) in proportion to the validator's stake weight's proportion of TAO. - - $$ - \text{proportional emissions (\%) to root stakers} - = \frac{\tau_{x}{} \, w_{\tau}} - {\alpha_{x} + \tau_{x} \, w_{\tau}} - $$ - - - Alpha is emitted to stakers on the mining subnet (i.e. stakers in alpha) in proportion to the validator's stake weight's proportion of alpha: - $$ - \text{proportional emissions (\%) to alpha stakers} - = \frac{\alpha_{x}} - {\alpha_{x} + \tau_{x} \, w_{\tau}} - $$ - - Validators who hold both root TAO and subnet alphas will extract both types of token. - - See [Core Dynamic TAO Concepts: Validator stake weight](../subnets/understanding-subnets#validator-stake-weight) - -### Note on evolution of Bittensor token economy - -When Dynamic TAO is initiated, there will be no alpha in circulation, so validator's stake weights will be entirely determined by their share of TAO stake. - -But far more alpha than TAO is emitted into circulation every block. As a result, over time there will be more alpha relative to TAO in overall circulation, and the relative weight of a validator in a given subnet will depend more on their alpha stake share relative to their share of the TAO stake on Subnet Zero. - -In order to hasten the process of alpha gaining the majority of stake power in the network, the contribution of TAO stake to validator stake weight is reduced by a global parameter called *TAO weight*. Currently, this is planned to be **18%**, in order to achieve a weight parity between TAO and total alpha in approximately 100 days. - -
- -
- -
\ No newline at end of file diff --git a/docs/errors/custom.md b/docs/errors/custom.md index 0c655c24bd..fab2aced6a 100644 --- a/docs/errors/custom.md +++ b/docs/errors/custom.md @@ -10,75 +10,117 @@ These errors are returned in the format: ```json { - "code": 1010, - "message": "Invalid Transaction", - "data": "Custom error: [Error Code]" + "code": 1010, + "message": "Invalid Transaction", + "data": "Custom error: [Error Code]" } ``` -Related: -- [Source code in GitHub](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/lib.rs#L1686) + +Related: + +- [Source code in GitHub](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/lib.rs#L1840-L1855) - [Subtensor Standard Errors](./subtensor.md) - Bittensor's custom error codes -- [Substrate Errors](https://polkadot.js.org/docs/substrate/errors/) - Errors from the underlying Substrate framework +- [Substrate Errors](https://polkadot.js.org/docs/substrate/errors/) - Errors from the underlying Substrate framework ## Error Codes ### Error Code 0 + **Error**: `ColdKeyInSwapSchedule` **Description**: Your coldkey is set to be swapped. No transfer operations are possible. ### Error Code 1 + **Error**: `StakeAmountTooLow` **Description**: The amount you are staking/unstaking/moving is below the minimum TAO equivalent. **Minimum**: 500,000 RAO (0.0005 TAO) ### Error Code 2 + **Error**: `BalanceTooLow` **Description**: The amount of stake you have is less than you have requested. ### Error Code 3 + **Error**: `SubnetDoesntExist` **Description**: This subnet does not exist. ### Error Code 4 + **Error**: `HotkeyAccountDoesntExist` **Description**: Hotkey is not registered on Bittensor network. ### Error Code 5 + **Error**: `NotEnoughStakeToWithdraw` **Description**: You do not have enough TAO equivalent stake to remove/move/transfer, including the unstake fee. ### Error Code 6 + **Error**: `RateLimitExceeded` **Description**: Too many transactions submitted (other than Axon serve/publish extrinsic). ### Error Code 7 + **Error**: `InsufficientLiquidity` **Description**: The subnet's pool does not have sufficient liquidity for this transaction. ### Error Code 8 + **Error**: `SlippageTooHigh` **Description**: The slippage exceeds your limit. Try reducing the transaction amount. ### Error Code 9 + **Error**: `TransferDisallowed` **Description**: This subnet does not allow stake transfer. ### Error Code 10 + **Error**: `HotKeyNotRegisteredInNetwork` **Description**: The hotkey is not registered in the selected subnet. ### Error Code 11 + **Error**: `InvalidIpAddress` **Description**: Axon connection info cannot be parsed into a valid IP address. ### Error Code 12 + **Error**: `ServingRateLimitExceeded` **Description**: Rate limit exceeded for axon serve/publish extrinsic. ### Error Code 13 + **Error**: `InvalidPort` **Description**: Axon connection info cannot be parsed into a valid port. +### Error Code 14 + +**Error**: `ZeroMaxAmount` +**Description**: The executable amount must be greater than zero. + +### Error Code 15 + +**Error**: `InvalidRevealRound` +**Description**: The provided reveal round is outdated or invalid. + +### Error Code 16 + +**Error**: `CommitNotFound` +**Description**: The referenced validator commit does not exist. + +### Error Code 17 + +**Error**: `CommitBlockNotInRevealRange` +**Description**: The referenced commit cannot be revealed in the current block range. + +### Error Code 18 + +**Error**: `InputLengthsUnequal` +**Description**: Attempted to batch reveal weights with mismatched vector input lenghts. + ### Error Code 255 + **Error**: `BadRequest` **Description**: Unclassified error. diff --git a/docs/errors/index.md b/docs/errors/index.md index aaa6b7e49a..e2fef265a2 100644 --- a/docs/errors/index.md +++ b/docs/errors/index.md @@ -7,6 +7,7 @@ title: "Subtensor Error Codes" This section documents the various types of errors that can arise from Subtensor, the blockchain underlying the Bittensor network. These errors can surface through different interfaces including the Bittensor CLI (`btcli`), the Bittensor Python SDK, or extrinsic transaction interfaces such as PolkadotJS. + Subtensor errors can be categorized into three main types: @@ -21,14 +22,14 @@ Most errors from the Bittensor network are returned in the following format: ```json { - "code": 1010, - "message": "Invalid Transaction", - "data": "Custom error: [Error Code]" + "code": 1010, + "message": "Invalid Transaction", + "data": "Custom error: [Error Code]" } ``` ## Related -- [Bittensor CLI](../btcli.md) - Command line interface documentation -- [Bittensor Python SDK](../bt-api-ref.md) - Python SDK documentation -- [Subtensor Nodes](../subtensor-nodes/index.md) - Information about running Subtensor nodes \ No newline at end of file +- [Bittensor CLI](../btcli/btcli.md) - Command line interface documentation +- [Bittensor Python SDK](../sdk/bt-api-ref.md) - Python SDK documentation +- [Subtensor Nodes](../subtensor-nodes/index.md) - Information about running Subtensor nodes diff --git a/docs/errors/subtensor.md b/docs/errors/subtensor.md index c3d5a5e6e0..e5e8d34994 100644 --- a/docs/errors/subtensor.md +++ b/docs/errors/subtensor.md @@ -6,12 +6,12 @@ title: "Subtensor Standard Errors" This page documents the standard errors that can arise from Subtensor, the blockchain underlying the Bittensor network. -Related: +Related: + - [Source code in GitHub](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/macros/errors.rs) - [Subtensor Custom Errors](./custom.md) -- [Substrate Errors](https://polkadot.js.org/docs/substrate/errors/) - Errors from the underlying Substrate framework +- [Substrate Errors](https://polkadot.js.org/docs/substrate/errors/) - Errors from the underlying Substrate framework - ## Network and Subnet Errors ### `SubNetworkDoesNotExist` @@ -21,6 +21,7 @@ The specified subnet does not exist. ### `RootNetworkDoesNotExist` The root network does not exist. + ### `SubnetNotExists` @@ -42,11 +43,13 @@ Operation is not permitted on the root subnet. ### `AllNetworksInImmunity` All subnets are in the immunity period. + ### `MechanismDoesNotExist` Trying to register a subnet into a mechanism that does not exist. + ### `SubNetRegistrationDisabled` @@ -111,6 +114,10 @@ Public key cannot be recovered. Recovered public key is invalid. +### `HotKeySwapOnSubnetIntervalNotPassed` + +Attempting a hotkey swap on subnet too frequently. + ## Stake and Balance Errors ### `NotEnoughStake` @@ -185,6 +192,10 @@ Transaction slippage is above your limit. Transfers are disallowed on this subnet. +### `InsufficientBalance` + +The caller does not have enough balance for the operation. + ## Weight Setting Errors ### `NeuronNoValidatorPermit` @@ -271,6 +282,18 @@ Alpha high value is too low (> 0.8 required). Alpha low value is out of allowed range (0 < alpha_low < 0.8). +### `IncorrectCommitRevealVersion` + +Incorrect commit-reveal version. + +### `RevealPeriodTooLarge` + +Reveal period is too large. + +### `RevealPeriodTooSmall` + +Reveal period is too small. + ## Rate Limiting Errors ### `ServingRateLimitExceeded` @@ -301,6 +324,10 @@ Default transaction rate limit exceeded. Childkey take rate limit exceeded. +### `StakingOperationRateLimitExceeded` + +Attempting staking operations too frequently. + ## Registration and Network Management ### `TooManyRegistrationsThisBlock` @@ -355,12 +382,50 @@ Proportion overflow when setting children. ### `TooManyChildren` -Too many children. +Too many children. ### `InvalidChildkeyTake` Childkey take is invalid. +## Subnet Leasing Errors + +### `InvalidLeaseBeneficiary` + +Invalid lease beneficiary to register the leased network. + +### `LeaseCannotEndInThePast` + +Lease cannot end in the past. + +### `LeaseNetuidNotFound` + +Couldn't find the lease netuid. + +### `LeaseDoesNotExist` + +Lease does not exist. + +### `LeaseHasNoEndBlock` + +Lease has no end block. + +### `LeaseHasNotEnded` + +Lease has not ended. + +### `Overflow` + +An overflow occurred. + +### `BeneficiaryDoesNotOwnHotkey` + +Beneficiary does not own hotkey. + +### `ExpectedBeneficiaryOrigin` + +Expected beneficiary origin. + ## Other Errors ### `InvalidIpType` @@ -407,6 +472,10 @@ Invalid identity. Activity cutoff is too low. +### `AdminActionProhibitedDuringWeightsWindow` + +Admin operation is prohibited during the protected weights window. + ### `CallDisabled` Call is disabled. @@ -419,3 +488,18 @@ SubToken disabled. Invalid netuid duplication. +### `SymbolDoesNotExist` + +Symbol does not exist. + +### `SymbolAlreadyInUse` + +Symbol already in use. + +### `BadOrigin` + +Wallet not authorized. Ensure that the account has the correct root or subnet owner permissions. + +### `InvalidValue` + +Generic error for out-of-range parameter value diff --git a/docs/errors-and-troubleshooting.md b/docs/errors/troubleshooting.md similarity index 86% rename from docs/errors-and-troubleshooting.md rename to docs/errors/troubleshooting.md index 34922ec656..64a420f117 100644 --- a/docs/errors-and-troubleshooting.md +++ b/docs/errors/troubleshooting.md @@ -4,7 +4,7 @@ title: "Troubleshooting" # Troubleshooting -This document presents helpful hints to troubleshoot the errors you may get while working in the Bittensor ecosystem. +This document presents helpful hints to troubleshoot the errors you may get while working in the Bittensor ecosystem. ## Priority is too low @@ -16,7 +16,6 @@ Running a `btcli` command sometimes gives me the below error: **Likely cause and remedy**: This means that you are submitting the same, duplicate transaction that you have already submitted. For example, if you are running a script, it is trying to submit transactions too quickly, most likely. You just have to wait for a few minutes before you run the command again. - ## SSLCertVerificationError Running any `btcli` command gives the following error, on macOS: @@ -36,14 +35,14 @@ Go to the folder where Python is installed, e.g., in my case (Mac OS) it is inst **Remedy 2**: Run the below commands: -- On macOS when not using any Python virtual environment: - ```bash - brew reinstall openssl - ``` +- On macOS when not using any Python virtual environment: + ```bash + brew reinstall openssl + ``` - On macOS when using a virtual environment: - ```bash - pip install urllib3 --force-reinstall - ``` + ```bash + pip install urllib3 --force-reinstall + ``` ## KeyFileError @@ -55,8 +54,8 @@ KeyFileError: Keyfile at: /path/to/.bittensor/wallets/some-coldkey/hotkeys/someh See: -- [Miner registration](./miners/index.md#miner-registration) -- [Validator registration](./validators/index.md#validator-registration) +- [Miner registration](../miners/index.md#miner-registration) +- [Validator registration](../validators/index.md#validator-registration) ## Balances.transfer not found @@ -64,8 +63,7 @@ See: ValueError: Call function 'Balances.transfer' not found ``` -**Likely cause and remedy**: You are working with an older version of Bittensor. Update your Bittensor to the latest version. See [Install Bittensor](./getting-started/installation.md). - +**Likely cause and remedy**: You are working with an older version of Bittensor. Update your Bittensor to the latest version. See [Install Bittensor](../getting-started/installation.md). ## Genesis mismatch @@ -75,4 +73,4 @@ Reason: Genesis mismatch. Banned, disconnecting. These messages are mostly harmless and you can ignore them. Your lite node will sync properly. See the "best" block numbers in the terminal log. If these block numbers are closer or approaching the current block as seen on either [https://bittensor.com/scan](https://bittensor.com/scan) or [Polkadot JS](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer), then your local node is syncing properly. -You get these error messages very often because one or the other Bittensor blockchain validator nodes is running an older version of Polkadot SDK. When it says, "Banned, disconnecting", it is saying the mismatched blockchain validator node is being disconnected. This usually is fine because you don't need to be connected to all the blockchain validator nodes. +You get these error messages very often because one or the other Bittensor blockchain validator nodes is running an older version of Polkadot SDK. When it says, "Banned, disconnecting", it is saying the mismatched blockchain validator node is being disconnected. This usually is fine because you don't need to be connected to all the blockchain validator nodes. diff --git a/docs/evm-tutorials/_create-btcli-wallet.mdx b/docs/evm-tutorials/_create-btcli-wallet.mdx new file mode 100644 index 0000000000..d9b30b62fa --- /dev/null +++ b/docs/evm-tutorials/_create-btcli-wallet.mdx @@ -0,0 +1,36 @@ +import React from "react"; + +/_ +Create Wallet with BTCLI +_/ + +export const CreateBtcliPartial = () => ( + <> + +
    +
  1. Install BTCLI if you haven't already: +

    + + pip install bittensor + +

    +
  2. +
  3. Create a new wallet: +

    + + btcli wallet new_coldkey --wallet.name my_wallet + +

    +
  4. +
  5. Note down your wallet's SS58 address, which you can get with: +

    + + btcli wallet overview --wallet.name my_wallet + +

    +
  6. +
  7. Your coldkey address will start with "5" and is in SS58 format (for example: 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty).
  8. +
+ + +); diff --git a/docs/evm-tutorials/_create-mm-wallet.mdx b/docs/evm-tutorials/_create-mm-wallet.mdx new file mode 100644 index 0000000000..33dc429034 --- /dev/null +++ b/docs/evm-tutorials/_create-mm-wallet.mdx @@ -0,0 +1,27 @@ +import React from "react"; + +/_ +Create Wallet with MetaMask +_/ + +export const CreatePartial = () => ( + <> + +
    +
  1. Install Metamask wallet browser extension, if you haven't already.
  2. +
  3. Create a new account or import an existing one.
  4. +
  5. Add the Bittensor EVM network to MetaMask: +
      +
    • Network Name: Bittensor EVM
    • +
    • RPC URL: https://test.chain.opentensor.ai
    • +
    • Chain ID: 945
    • +
    • Currency Symbol: TAO
    • +
    • Block Explorer URL: test.chain.opentensor.ai
    • +
    +
  6. +
  7. Click Save.
  8. +
  9. Click Switch network.
  10. +
+ + +); diff --git a/docs/evm-tutorials/_install.mdx b/docs/evm-tutorials/_install.mdx new file mode 100644 index 0000000000..70a08abe44 --- /dev/null +++ b/docs/evm-tutorials/_install.mdx @@ -0,0 +1,37 @@ +/_ +Install the EVM Examples repo +_/ + +export const InstallPartial = () => ( + <> +
    +
  1. + Clone the Opentensor EVM-Bittensor GitHub repo: +

    + + git clone https://github.com/opentensor/evm-bittensor.git + +

    +
  2. + +
  3. + Navigate to evm-bittensor directory: +

    + + cd evm-bittensor + +

    +
  4. + +
  5. + Install the dependencies: + + + yarn install + + +
  6. +
+ + +); diff --git a/docs/evm-tutorials/bridge-vtao.md b/docs/evm-tutorials/bridge-vtao.md new file mode 100644 index 0000000000..7b43ca4f08 --- /dev/null +++ b/docs/evm-tutorials/bridge-vtao.md @@ -0,0 +1,43 @@ +--- +title: "Token Bridging" +--- + +# Token Bridging + +This guide provides an overview of two related topics: +- how to moves TAO between Substrate-style wallets (SS58) and the Etherum style wallets on Bittensor EVM +- how to use vTAO as a token bridge between Bittensor EVM and other EVM chains. + +:::info +Bittensor EVM smart contracts are executed solely on the **Bittensor blockchain, _not_ on the Ethereum blockchain.** +::: + +## Transferring liquidity between Substrate and EVM Wallets on Bittensor Chain + +**TAO** is the native token of the Bittensor network it exists on Subtensor, Bittensor's blockchain, which is built on top of Substrate. Hence, TAO is normally held in Substrate-style, ss58-format wallets, which can be used to execute Subtensor blockchain extrinsics, including through the Bittensor Python SDK and BTCLI. + +See [Wallets, Coldkeys and Hotkeys in Bittensor](../keys/wallets) + +If TAO is transferred to an Ethereum-style h160 wallet, it can be used in Bittensor's EVM layer. This is the same token, just represented in a different account format. + +You can move TAO back and forth between Substrate and EVM wallets several ways: +Use example scripts: + - [Transfer TAO from H160 to SS58](./convert-h160-to-ss58) + - [Transfer TAO from SS58 to H160](./transfer-from-metamask-to-ss58) +- Using [`tao.app/bridge`](https://tao.app/bridge). + +- Using OTF's EVM Bridge: [`bridge.bittensor.com/`](https://bridge.bittensor.com/) + +## Bridge to other EVM Chains with vTAO + +vTAO is a liquid-staked TAO token on the Subtensor EVM, available through ['tao.app/bridge'](https://tao.app/bridge). + +- vTAO is minted by depositing TAO into a staking contract, the vTAO can later be redeemed for an amount of TAO depending on the exchange rate. +- Your wallet balance in vTAO stays the same, but the underlying TAO locked in the contract increases with staking rewards. +- vTAO can be bridged between supported EVM chains. + +:::tip +vTAO conceptually similar to [Lido's wstETH](https://docs.lido.fi/contracts/wsteth/). +::: + + diff --git a/docs/evm-tutorials/convert-h160-to-ss58.md b/docs/evm-tutorials/convert-h160-to-ss58.md new file mode 100644 index 0000000000..bb46fecefa --- /dev/null +++ b/docs/evm-tutorials/convert-h160-to-ss58.md @@ -0,0 +1,101 @@ +--- +title: "Convert Ethereum (H160) Address to Substrate (SS58)" +--- + +import { InstallPartial } from "./\_install.mdx"; +import { CreatePartial } from "./\_create-mm-wallet.mdx"; + +# Convert Ethereum (H160) Address to Substrate (SS58) + +This tutorial demonstrates how to convert between Ethereum (H160) and Substrate (SS58) addresses. This is useful for moving across the boundary between [EVM wallets and Subtensor Wallets on the Bittensor blockchain](./index.md#evm-and-subtensor-wallets-on-the-bittensor-blockchian). + +In what follows, we'll create a wallet in Metamask and convert it's public key to ss58 format in order to target it with a balance transfer using BTCLI. + +## Procedure + +### Create Wallet with MetaMask + + + +### Install the EVM Examples repo + + + +## Set your config + +### Convert Address for Bittensor + +Run the `convert-address.js` script by navigating to the `examples` folder and running the following command: + +```bash +node convert-address.js +``` + +:::warning Replace the placeholder address +Within the `examples/convert-address` file, replace the placeholder `ethereumAddress` argument with your own Ethereum wallet address. +::: + +Note down the SS58 address output by the script—this is your wallet's Subtensor address on the Bittensor network. + +### Transfer TAO to EVM Wallet + +Use `btcli` to transfer TAO to your SS58 address. Here we will use test network. + +```bash +btcli wallet transfer --destination --network test +``` + +### Verify Balance in MetaMask + +1. Open MetaMask +2. Ensure you're connected to the Bittensor EVM network +3. Your TAO balance should now be visible in MetaMask +4. You can now use this wallet for EVM transactions on Bittensor + +## Conversion Script + +Below is the code used above for the conversion. + +**Source code**: + +- [EVM examples repo](https://github.com/opentensor/evm-bittensor) +- [Address mapping](https://github.com/opentensor/evm-bittensor/blob/main/examples/address-mapping.js) +- [Convert address](https://github.com/opentensor/evm-bittensor/blob/main/examples/convert-address.js) + +```javascript +//convert-address.js + +const { convertH160ToSS58 } = require("./address-mapping.js"); + +async function main() { + const ethereumAddress = "0xbdA293c21DfCaDDAeB9aa8b98455d42325599d23"; + + const ss58Address = convertH160ToSS58(ethereumAddress); + console.log(`ss58 mirror: ${ss58Address}`); +} + +main().catch(console.error); +``` + +```javascript +// address-mapping.js +function convertH160ToSS58(ethAddress) { + const prefix = "evm:"; + const prefixBytes = new TextEncoder().encode(prefix); + const addressBytes = hexToU8a( + ethAddress.startsWith("0x") ? ethAddress : `0x${ethAddress}` + ); + const combined = new Uint8Array(prefixBytes.length + addressBytes.length); + + // Concatenate prefix and Ethereum address + combined.set(prefixBytes); + combined.set(addressBytes, prefixBytes.length); + + // Hash the combined data (the public key) + const hash = blake2AsU8a(combined); + + // Convert the hash to SS58 format + const ss58Address = encodeAddress(hash, 42); // Network ID 42 for Bittensor + return ss58Address; +} +``` diff --git a/docs/evm-tutorials/ed25519-verify-precompile.md b/docs/evm-tutorials/ed25519-verify-precompile.md index 1aae5a4488..b7799f80c1 100644 --- a/docs/evm-tutorials/ed25519-verify-precompile.md +++ b/docs/evm-tutorials/ed25519-verify-precompile.md @@ -1,47 +1,187 @@ --- -title: "Ed25519 Verify Precompile" +title: "Verify Address Precompile" --- import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; -# Ed25519 Verify Precompile +# Verify Address Precompile -This precompile is deployed on the subtensor EVM at the address `0x0000000000000000000000000000000000000402`. This precompile allows you to verify an `ed25519` signature. +The Ed25519 Verify Precompile allows EVM smart contracts to verify Ed25519 signatures, which are commonly used in Substrate-based chains like Bittensor. This is essential for bridging identity and ownership between Substrate and EVM ecosystems. For example, you may want to verify coldkey ownership before transferring to someone. EVM functionality doesn't allow transferring directly to a `ss58` address—like the public key of a Bittensor coldkey—because EVM uses the H160 address schema. To bridge the gap, you can use this precompile to prove a claim of ownership. The owner of a coldkey can send an EVM transaction with a signed message, serving as proof of ownership of the coldkey's `ss58` address. -You can use this precompile to verify proof of `ss58` account ownership on the EVM side. For example, you may need to do such verification for an airdrop to TAO owners. While EVM functionality doesn't allow airdropping directly to `ss58` addresses (because EVM is using H160 address schema), one can implement an airdrop via claiming. An owner of `ss58` address eligible for an airdrop can send an EVM transaction which includes the proof of `ss58` address ownership, for example, a signed message, uniquely specific for a given airdrop. +## Prerequisites -For a complete code example see [`ed25519-verify.js`](https://github.com/opentensor/evm-bittensor/blob/main/examples/ed25519-verify.js). +- **Node.js** (v16 or later recommended) +- **npm** or **yarn** +- [Clone the Bittensor EVM examples repo](./install.md) +- [Get set up for using EVM wallet on testnet](./evm-testnet-with-metamask-wallet) +- [Install](./install) the EVM-Bittensor repo, containing scripts and examples. -:::danger Stop. Did you install the dependencies? -Before you proceed, make sure you finished the [Install](./install.md) step. -::: - -## Run +## Example Navigate to the `examples` directory of the EVM-Bittensor repo: - ```bash - cd examples - ``` +```bash +cd examples +``` + To run this precompile, execute: - ```bash - node ed25519-verify.js - ``` +```bash +node ed25519-verify.js +``` This example demonstrates how to: -1. Sign an arbitrary message with `ed25519` key. +1. Sign an arbitrary message with `ed25519` key. +2. Verify the signature using the precompile contract. +3. Fail the verification of the signature using a corrupted message hash with the precompile contract. +4. Fail the verification of a corrupted signature with the precompile contract. - Any substrate keyring can be initialized as `ed25519` with the same seed phrase or private key as used for signing subtensor transactions, even if they are usually used to create `sr25519` signatures. - - The precompile only allows verification of 32-byte messages. However, the arbitrary message can be converted into 32-byte message by calculating the message hash (like it is done in this below example): +[On GitHub](https://github.com/opentensor/evm-bittensor/blob/main/examples/ed25519-verify.js). - ```javascript - const messageHash = ethers.keccak256(messageHex); // Hash the message to fit into bytes32 - ``` +
+ Full code +```js +const { ethers } = require('ethers'); +const { Keyring } = require('@polkadot/keyring'); -2. Verify the signature using the precompile contract. -3. Fail the verification of the signature using the corrupted message hash with the precompile contract. -4. Fail the verification of the corrupted signature with the precompile contract. \ No newline at end of file +// PROTECT YOUR PRIVATE KEYS WELL, NEVER COMMIT THEM TO GITHUB OR SHARE WITH ANYONE +const { rpcUrl } = require('./config.js'); + +const provider = new ethers.JsonRpcProvider(rpcUrl); + +const IED25519VERIFY_ADDRESS = '0x0000000000000000000000000000000000000402'; +const IEd25519VerifyABI = [ +{ +"inputs": [ +{ "internalType": "bytes32", "name": "message", "type": "bytes32" }, +{ "internalType": "bytes32", "name": "publicKey", "type": "bytes32" }, +{ "internalType": "bytes32", "name": "r", "type": "bytes32" }, +{ "internalType": "bytes32", "name": "s", "type": "bytes32" } +], +"name": "verify", +"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], +"stateMutability": "pure", +"type": "function" +} +]; + +async function main() { +const keyring = new Keyring({ type: 'ed25519' }); +const myAccount = keyring.addFromUri('//Alice'); + +////////////////////////////////////////////////////////////////////// +// Generate a signature + +// Your message to sign +const message = 'Sign this message'; +const messageU8a = new TextEncoder().encode(message); +const messageHex = ethers.hexlify(messageU8a); // Convert message to hex string +const messageHash = ethers.keccak256(messageHex); // Hash the message to fit into bytes32 +console.log(`messageHash = ${messageHash}`); +const hashedMessageBytes = hexToBytes(messageHash); + +// Sign the message +const signature = myAccount.sign(hashedMessageBytes); +console.log(`Signature: ${bytesToHex(signature)}`); + +// Verify the signature locally +const isValid = myAccount.verify(hashedMessageBytes, signature, myAccount.publicKey); +console.log(`Is the signature valid? ${isValid}`); + +////////////////////////////////////////////////////////////////////// +// Verify the signature using the precompile contract + +const publicKeyBytes = bytesToHex(myAccount.publicKey); +console.log(`publicKeyBytes = ${publicKeyBytes}`); + +// Split signture into Commitment (R) and response (s) +let r = signature.slice(0, 32); // Commitment, a.k.a. "r" - first 32 bytes +let s = signature.slice(32, 64); // Response, a.k.a. "s" - second 32 bytes +let rBytes = bytesToHex(r); +let sBytes = bytesToHex(s); +const ed25519Contract = new ethers.Contract(IED25519VERIFY_ADDRESS, IEd25519VerifyABI, provider); +const isPrecompileValid = await ed25519Contract.verify(messageHash, publicKeyBytes, rBytes, sBytes); +console.log(`Is the signature valid according to the smart contract? ${isPrecompileValid}`); + +////////////////////////////////////////////////////////////////////// +// Verify the signature for bad data using the precompile contract + +let brokenHashedMessageBytes = hashedMessageBytes; +brokenHashedMessageBytes[0] = (brokenHashedMessageBytes[0] + 1) % 0xff; +const brokenMessageHash = bytesToHex(brokenHashedMessageBytes); +console.log(`brokenMessageHash = ${brokenMessageHash}`); +const isPrecompileValidBadData = await ed25519Contract.verify(brokenMessageHash, publicKeyBytes, rBytes, sBytes); +console.log(`Is the signature valid according to the smart contract for broken data? ${isPrecompileValidBadData}`); + +////////////////////////////////////////////////////////////////////// +// Verify the bad signature for good data using the precompile contract + +let brokenR = r; +brokenR[0] = (brokenR[0] + 1) % 0xff; +rBytes = bytesToHex(r); +const isPrecompileValidBadSignature = await ed25519Contract.verify(messageHash, publicKeyBytes, rBytes, sBytes); +console.log(`Is the signature valid according to the smart contract for broken signature? ${isPrecompileValidBadSignature}`); +} + +main().catch(console.error); + +function hexToBytes(hex) { +// Remove the '0x' prefix if it exists +if (hex.startsWith('0x')) { +hex = hex.slice(2); +} + +// Initialize the array +var bytes = new Uint8Array(hex.length / 2); + +// Loop through each pair of characters +for (var i = 0; i < bytes.length; i++) { +// Convert the pair of characters to a byte +bytes[i] = parseInt(hex.substr(i \* 2, 2), 16); +} + +return bytes; +} + +function bytesToHex(bytes) { +// Initialize the hex string +var hex = []; + +// Loop through each byte +for (var i = 0; i < bytes.length; i++) { +// Convert each byte to a hex string and add it to the array +// Ensure it is two digits by padding with a zero if necessary +hex.push((bytes[i] >>> 4).toString(16)); +hex.push((bytes[i] & 0xF).toString(16)); +} + +// Join all hex string parts into one string +return '0x' + hex.join(''); +} + +``` +
+## Example Output + +``` + +node ed25519-verify.js +@polkadot/util has multiple versions, ensure that there is only one installed. +Either remove and explicitly install matching versions or dedupe using your package manager. +The following conflicting packages were found: +cjs 12.2.1 node_modules/@polkadot/keyring/node_modules/@polkadot/util/cjs +cjs 13.5.1 node_modules/@polkadot/util/cjs +messageHash = 0xd6ce89c7d4f347455c7dddf19b42e0357edd7587b73b81b384810253c3c3c8ff +Signature: 0x35c3c28c3470ea348343cea4881bd353843236df73a04300261cb86411fe88a05a196842849eb1ef4335b1f171a70e74d2d4c8d3b71ad6a41b6fa48afec85b01 +Is the signature valid? true +publicKeyBytes = 0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee +Is the signature valid according to the smart contract? true +brokenMessageHash = 0xd7ce89c7d4f347455c7dddf19b42e0357edd7587b73b81b384810253c3c3c8ff +Is the signature valid according to the smart contract for broken data? false +Is the signature valid according to the smart contract for broken signature? false + +``` + +``` diff --git a/docs/evm-tutorials/evm-localnet-with-metamask-wallet.md b/docs/evm-tutorials/evm-localnet-with-metamask-wallet.md index 856493d9e8..a4d9dab7e1 100644 --- a/docs/evm-tutorials/evm-localnet-with-metamask-wallet.md +++ b/docs/evm-tutorials/evm-localnet-with-metamask-wallet.md @@ -1,20 +1,19 @@ --- -title: "EVM Localnet with Metamask Wallet" +title: "EVM on Local Chain" --- import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; -# EVM Localnet with Metamask Wallet +# EVM on Local Chain -This tutorial is for how to set up your Metamask wallet to use with EVM localnet on Bittensor. You must run either this step or [EVM Testnet with Metamask Wallet](./evm-testnet-with-metamask-wallet.md) tutorial before you can run other tutorials in this section. +This page covers getting set up to use EVM on a locally deployed Bittensor blockchain. -:::tip blog post: EVM on Bittensor -If you are new to EVM, try this [blog post](https://blog.bittensor.com/evm-on-bittensor-draft-6f323e69aff7) for a simplified explanation. -::: +Consider first trying [EVM with Bittensor testnet](./evm-testnet-with-metamask-wallet.md). This allows you to try EVM without having to deploy a blockchain locally, but you will have to obtain testnet TAO by inquiring in discord, or by completing the [BTCLI playground](../btcli/btcli-playground)challenge to obtain testnet TAO. Key values: -- **EVM Subtensor Mainnet Chain ID:**: `964` (UTF-8 encoded TAO symbol) + +- **EVM Subtensor Mainnet Chain ID:**: `964` (UTF-8 encoded TAO symbol) - **EVM Subtensor Testnet Chain ID:**: `945` (UTF-8 encoded alpha character) - **Opentensor EVM-Bittensor GitHub repo with code examples:** https://github.com/opentensor/evm-bittensor/tree/main @@ -33,7 +32,7 @@ The bare local network doesn't have the Chain ID setup and it needs to be config adminUtils >> sudoSetEvmChainId ``` -## Step 3. Create a Metamask wallet +## Step 3. Create a Metamask wallet 1. If you don't already have it, [install Metamask wallet](https://metamask.io/download/) browser extension. 2. Create a new account. @@ -42,17 +41,17 @@ adminUtils >> sudoSetEvmChainId Follow the below steps: -1. Open Metamask Wallet extension on your browser. Click on the drop-down **Select a network** menu at the top left. -2. Click on **+ Add a Custom Network** button. +1. Open Metamask Wallet extension on your browser. Click on the drop-down **Select a network** menu at the top left. +2. Click on **+ Add a Custom Network** button. 3. Enter the following details: - - **Network name:** "Subtensor Local" - - **Default RPC URL:** http://localhost:9944/ - - **Chain ID:** `964` or `945`, depending on your setting in Step 2 - - **Currency symbol:** TAO -6. Click **Save**. -7. Click on **Select a network** again and switch to the Subtensor Local network. + - **Network name:** "Subtensor Local" + - **Default RPC URL:** http://localhost:9944/ + - **Chain ID:** `964` or `945`, depending on your setting in Step 2 + - **Currency symbol:** TAO +4. Click **Save**. +5. Click on **Select a network** again and switch to the Subtensor Local network. -With the above steps, you have successfully configured your Metamask wallet with the EVM localnet. +With the above steps, you have successfully configured your Metamask wallet with the EVM localnet. ## Step 5. Configure private key and RPC endpoint @@ -60,42 +59,42 @@ With the above steps, you have successfully configured your Metamask wallet with Before you proceed, make sure you finished the [Install](./install.md) step. ::: -In this step you will copy the private key from your Metamask wallet account and paste it into the configuration file in the repo. This step will ensure that you are not prompted with password each and every step as you run these tutorials. - +In this step you will copy the private key from your Metamask wallet account and paste it into the configuration file in the repo. This step will ensure that you are not prompted with password each and every step as you run these tutorials. 1. Navigate to the `examples` directory of the EVM-Bittensor repo: - ```bash - cd examples - ``` + ```bash + cd examples + ``` 2. Create `config.js` file by copying the `config-example.js` file: - ```bash - cp config-example.js config.js - ``` + ```bash + cp config-example.js config.js + ``` -3. On Metamask wallet extension, your wallet account will have a H160 account address, starting with the `0x` prefix (for example: `0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf`), and also your wallet account name. -4. Click on your wallet account name, which will open the drop-down menu. -5. Click on the ⋮ (three vertical dots, i.e., vertical ellipsis) next to the wallet account and select **Account details**. It will open a view with a QR code, your wallet account H160 address and a **Show private key** button. +3. On Metamask wallet extension, your wallet account will have a H160 account address, starting with the `0x` prefix (for example: `0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf`), and also your wallet account name. +4. Click on your wallet account name, which will open the drop-down menu. +5. Click on the **⋮** (three vertical dots, i.e., vertical ellipsis) next to the wallet account and select **Account details**. It will open a view with a QR code, your wallet account H160 address and a **Show private key** button. 6. Click on the **Show private key** button, enter the password. You will then see the private key for your wallet account. Copy this private key. -7. Paste this private key into `ethPrivateKey` string in your `config.js` file as shown below (mangled for security): - - ```javascript - const ethPrivateKey = "02c1c4112233snipsnipsnipgh933aca491e090e0b7xxyy1b124b86d9382b01a8"; - ``` - -8. Finally, edit the `module.exports` section of the `config.js` file to use the localnet URLs, as shown below: - ```javascript - module.exports = { - ethPrivateKey, - subSeed, - rpcUrl: rpcUrlLocal, - wsUrl: wsUrlLocal, - } - ``` - -Save the `config.js` file. Now your setup is ready to run the tutorials with EVM localnet. +7. Paste this private key into `ethPrivateKey` string in your `config.js` file as shown below (mangled for security): + + ```javascript + const ethPrivateKey = + "02c1c4112233snipsnipsnipgh933aca491e090e0b7xxyy1b124b86d9382b01a8"; + ``` + +8. Finally, edit the `module.exports` section of the `config.js` file to use the localnet URLs, as shown below: + ```javascript + module.exports = { + ethPrivateKey, + subSeed, + rpcUrl: rpcUrlLocal, + wsUrl: wsUrlLocal, + }; + ``` + +Save the `config.js` file. Now your setup is ready to run the tutorials with EVM localnet. ## Step 6 (Optional). Disable white list for contract deployment diff --git a/docs/evm-tutorials/evm-mainnet-with-metamask-wallet.md b/docs/evm-tutorials/evm-mainnet-with-metamask-wallet.md index 7a7d2465e2..6aa1c37da7 100644 --- a/docs/evm-tutorials/evm-mainnet-with-metamask-wallet.md +++ b/docs/evm-tutorials/evm-mainnet-with-metamask-wallet.md @@ -1,24 +1,21 @@ --- -title: "EVM Mainnet with Metamask Wallet" +title: "EVM on Mainnet" --- + import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; -# EVM Mainnet with Metamask Wallet - -This tutorial is for how to set up your Metamask wallet to use with the Mainnet (finney) on Bittensor. You must run this step before you can run other tutorials in this section. +# EVM on Mainnet -:::tip blog post: EVM on Bittensor -If you are new to EVM, try this [blog post](https://blog.bittensor.com/evm-on-bittensor-draft-6f323e69aff7) for a simplified explanation. -::: +This page covers how to set up your Metamask wallet to use with the Mainnet (finney) on Bittensor. You must run this step before you can run other tutorials in this section. Key values: + - The **Bittensor Mainnet URL:** `https://lite.chain.opentensor.ai` - **EVM Subtensor Chain ID:** `964` (UTF-8 encoded TAO symbol) - **Opentensor EVM-Bittensor GitHub repo:** `https://github.com/opentensor/evm-bittensor/tree/main` - -## Step 1. Create a Metamask wallet +## Step 1. Create a Metamask wallet 1. If you don't already have it, [install Metamask wallet](https://metamask.io/download/) browser extension. 2. Create a new account. @@ -33,23 +30,23 @@ Open [Subtensor page on ChainList.org](https://chainlist.org/chain/964) and clic Add the Mainnet to Metamask from within the Metamask wallet. Follow the below steps: -1. Open Metamask Wallet extension on your browser. Click on the ⋮ (three vertical dots, i.e., vertical ellipsis) at the top right. -2. Select **Settings** from the drop-down menu. +1. Open Metamask Wallet extension on your browser. Click on the ⋮ (three vertical dots, i.e., vertical ellipsis) at the top right. +2. Select **Settings** from the drop-down menu. 3. Select **Networks** > **Add network**. 4. Click on **Add a network manually** at the bottom of the networks list. 5. Enter the following details: - - **Network name:** "Subtensor" - - **EVM RPC URL:** `https://lite.chain.opentensor.ai` - - **Chain ID:** `964` - - **Currency symbol:** TAO + - **Network name:** "Subtensor" + - **EVM RPC URL:** `https://lite.chain.opentensor.ai` + - **Chain ID:** `964` + - **Currency symbol:** TAO 6. Click **Save**. 7. Then click on **Switch network**. -With the above steps, you have successfully configured your Metamask wallet with the Mainnet. +With the above steps, you have successfully configured your Metamask wallet with the Mainnet. ## Step 3 Obtain TAO -We cannot provide you with specific advice for where/how to obtain TAO; however, if you need to transfer tokens to the account you created in MetaMask, use a site like https://snow-address-converter.netlify.app/ to convert your H160-format address (the one that starts with "0x") to substrate's SS58 version (starting with "5"). When sending TAO to your account from an account managed via substrate wallet applications and/or exchange accounts, use the SS58 version of the address as the destination. +We cannot provide you with specific advice for where/how to obtain TAO; however, if you need to transfer tokens to the account you created in MetaMask, use a site like https://snow-address-converter.netlify.app/ to convert your H160-format address (the one that starts with "0x") to substrate's SS58 version (starting with "5"). When sending TAO to your account from an account managed via substrate wallet applications and/or exchange accounts, use the SS58 version of the address as the destination. ## Step 4. Copy Metamask wallet private key into config @@ -57,28 +54,29 @@ We cannot provide you with specific advice for where/how to obtain TAO; however, Before you proceed, make sure you finished the [Install](./install.md) step. ::: -In this step you will copy the private key from your Metamask wallet account and paste it into the configuration file in the repo. This step will ensure that you are not prompted with password each and every step as you run these tutorials. - +In this step you will copy the private key from your Metamask wallet account and paste it into the configuration file in the repo. This step will ensure that you are not prompted with password each and every step as you run these tutorials. 1. Navigate to the `examples` directory of the EVM-Bittensor repo: - ```bash - cd examples - ``` + ```bash + cd examples + ``` 2. Create `config.js` file by copying the `config-example.js` file: - ```bash - cp config-example.js config.js - ``` + ```bash + cp config-example.js config.js + ``` -3. On Metamask wallet extension, your wallet account will have a H160 account address, starting with the `0x` prefix (for example: `0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf`), and also your wallet account name. -4. Click on your wallet account name, which will open the drop-down menu. -5. Click on the ⋮ (three vertical dots, i.e., vertical ellipsis) next to the wallet account and select **Account details**. It will open a view with a QR code, your wallet account H160 address and a **Show private key** button. +3. On Metamask wallet extension, your wallet account will have a H160 account address, starting with the `0x` prefix (for example: `0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf`), and also your wallet account name. +4. Click on your wallet account name, which will open the drop-down menu. +5. Click on the **⋮** (three vertical dots, i.e., vertical ellipsis) next to the wallet account and select **Account details**. It will open a view with a QR code, your wallet account H160 address and a **Show private key** button. 6. Click on the **Show private key** button, enter the password. You will then see the private key for your wallet account. Copy this private key. 7. Paste this private key into `ethPrivateKey` string in your `config.js` file as shown below (mangled for security): ```javascript -const ethPrivateKey = "02c1c4112233snipsnipsnipgh933aca491e090e0b7xxyy1b124b86d9382b01a8"; +const ethPrivateKey = + "02c1c4112233snipsnipsnipgh933aca491e090e0b7xxyy1b124b86d9382b01a8"; ``` -Save the `config.js` file. Now your setup is ready to run the tutorials with EVM Mainnet. + +Save the `config.js` file. Now your setup is ready to run the tutorials with EVM Mainnet. diff --git a/docs/evm-tutorials/evm-on-subtensor.md b/docs/evm-tutorials/evm-on-subtensor.md deleted file mode 100644 index cfa49fff9a..0000000000 --- a/docs/evm-tutorials/evm-on-subtensor.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "EVM on Subtensor" ---- - -import ThemedImage from '@theme/ThemedImage'; -import useBaseUrl from '@docusaurus/useBaseUrl'; - -# EVM on Subtensor - -Ethereum compatibility layer is now available on the subtensor. Using this EVM feature you can: -- Deploy and interact with any Ethereum smart contract, without any need to change it, on the subtensor blockchain. -- Access all the standard Ethereum JSON-RPC methods from this EVM compatibility layer on Bittensor. - -When this EVM feature is turned ON, it allows the subtensor blockchain to execute Ethereum-compatible smart contracts. - -:::danger EVM smart contract executes on subtensor -Note that all operations performed by the subtensor EVM feature are executed solely on the subtensor blockchain, not on the Ethereum blockchain. -::: - -This document explains in simple terms what this EVM on subtensor is and how it works. Head on over to the [EVM Tutorials](./index.md) to start learning how to use this feature. - -## Ethereum vs Bittensor smart contracts - -On the Ethereum network, nodes such as full nodes, validator nodes and archive nodes run the Ethereum Virtual Environment (EVM) run-time environment. Smart contracts operate under this EVM. See the below high-level diagram. - -When we say “smart contracts on Bittensor” we refer to the new EVM compability feature in the Bittensor subtensor blockchain. When this EVM feature is turned ON, it allows the subtensor blockchain to execute Ethereum-compatible smart contracts. **Note that all operations performed by this new subtensor EVM feature are executed solely on the subtensor blockchain, not on the Ethereum blockchain.** See the below diagram showing how smart contracts on subtensor work: - - - - - - - - - - -Next, see [EVM Tutorials](./index.md) to start learning how to use this feature. diff --git a/docs/evm-tutorials/evm-testnet-with-metamask-wallet.md b/docs/evm-tutorials/evm-testnet-with-metamask-wallet.md index 17079ed1be..4144ed906e 100644 --- a/docs/evm-tutorials/evm-testnet-with-metamask-wallet.md +++ b/docs/evm-tutorials/evm-testnet-with-metamask-wallet.md @@ -1,17 +1,14 @@ --- -title: "EVM Testnet with Metamask Wallet" +title: "EVM on Testnet" --- import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; +import { CreatePartial } from "./\_create-mm-wallet.mdx"; -# EVM Testnet with Metamask Wallet +# EVM on Testnet -This tutorial is for how to set up your Metamask wallet to use with the testnet on Bittensor. You must run this step before you can run other tutorials in this section. - -:::tip blog post: EVM on Bittensor -If you are new to EVM, try this [blog post](https://blog.bittensor.com/evm-on-bittensor-draft-6f323e69aff7) for a simplified explanation. -::: +This page covers how to set up your Metamask wallet to use with the testnet on Bittensor. You must run this step before you can run other tutorials in this section. Key values: @@ -19,12 +16,26 @@ Key values: - **EVM Subtensor Chain ID:** `945` (UTF-8 encoded alpha character) - **Opentensor EVM-Bittensor GitHub repo:** `https://github.com/opentensor/evm-bittensor/tree/main` -## Step 1. Create a Metamask wallet +## Create Wallet with MetaMask + + + +## Connect to EVM Testnet + +Confirm the EVM node is online and accessible. You can check the node status independently using `curl` or similar tools: -1. If you don't already have it, [install Metamask wallet](https://metamask.io/download/) browser extension. -2. Create a new account. +```bash +curl -X POST \ + -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ + https://test.chain.opentensor.ai +``` + +```console +{"jsonrpc":"2.0","id":1,"result":"0x460943"} +``` -### Step 2. Add testnet to Metamask +### Add testnet to Metamask Add the testnet to Metamask from within the Metamask wallet. Follow the below steps: @@ -42,15 +53,11 @@ Add the testnet to Metamask from within the Metamask wallet. Follow the below st With the above steps, you have successfully configured your Metamask wallet with the testnet. -## Step 3 Obtain TAO - -Next, request testnet TAO in the Bittensor community [Discord](https://discord.com/channels/799672011265015819/1107738550373454028/threads/1331693251589312553). Alternatively, you can transfer some testnet TAO to your wallet address using the [BTCLI Live Coding Playground](../btcli/btcli-playground.md#transfer). +## Obtain TAO -## Step 4. Copy Metamask wallet private key into config +Next, request testnet TAO in the Bittensor community [Discord](https://discord.com/channels/799672011265015819/1107738550373454028/threads/1331693251589312553). Alternatively, you can obtain testnet TAO through the [BTCLI Live Coding Playground](../btcli/btcli-playground.md#transfer). -:::danger Stop. Did you install the dependencies? -Before you proceed, make sure you finished the [Install](./install.md) step. -::: +## Copy Metamask wallet private key into config In this step you will copy the private key from your Metamask wallet account and paste it into the configuration file in the repo. This step will ensure that you are not prompted with password each and every step as you run these tutorials. diff --git a/docs/evm-tutorials/examples.md b/docs/evm-tutorials/examples.md new file mode 100644 index 0000000000..1a1eaa7082 --- /dev/null +++ b/docs/evm-tutorials/examples.md @@ -0,0 +1,49 @@ +--- +title: "Bittensor EVM: Examples and Precompiles" +--- + +import { InstallPartial } from "./\_install.mdx"; + +# Bittensor EVM: Examples and Precompiles + +## Available Precompiles + +The following precompiled smart contracts are available on the Bittensor EVM. +The source code can be found [on GitHub](https://github.com/opentensor/subtensor/blob/main/precompiles). + +Code examples used throughout this section are provided by the _Opentensor Foundation_ (_OTF_), and come from [this repository](https://github.com/opentensor/evm-bittensor/tree/main/examples). + +## Examples + +- [Convert Ethereum (H160) Address to Substrate (SS58)](./convert-h160-to-ss58): Learn how to convert between H160 and SS58 address formats + +## Standard Ethereum Precompiles + +- `ECRecover` (0x1): Recover the address associated with the public key from elliptic curve signature +- `Sha256` (0x2): SHA-256 hash function +- `Ripemd160` (0x3): RIPEMD-160 hash function +- `Identity` (0x4): Identity function (returns input data) +- `Modexp` (0x5): Modular exponentiation +- `Sha3FIPS256` (0x400): SHA3-256 hash function (FIPS variant) +- `ECRecoverPublicKey` (0x401): Recover the public key from an elliptic curve signature + +## Bittensor-Specific Precompiles + +The following list consists of Bittensor-specific precompiles with links to their respective documentation: + +- [`Ed25519Verify`](./ed25519-verify-precompile.md): Verify Ed25519 signatures +- [`BalanceTransfer`](./transfer-between-two-h160-accounts.md): Transfer TAO between accounts +- [`StakingPrecompile`](./staking-precompile.md): Manage staking operations +- [`StakingPrecompileV2`](./staking-precompile.md) (0x805): Main staking operations including: + - `addStake`: Add stake to a hotkey + - `removeStake`: Remove stake from a hotkey + - `moveStake`: Move stake between hotkeys + - `transferStake`: Transfer stake between coldkeys + - `getTotalColdkeyStake`: Get total stake for a coldkey + - `getTotalHotkeyStake`: Get total stake for a hotkey + - `getStake`: Get stake between specific hotkey and coldkey + - `addProxy`: Add a proxy delegate + - `removeProxy`: Remove a proxy delegate +- [`SubnetPrecompile`](./subnet-precompile.md): Manage subnet operations +- [`MetagraphPrecompile`](./metagraph-precompile.md): Interact with the metagraph +- [`NeuronPrecompile`](./neuron-precompile.md): Manage neuron operations diff --git a/docs/evm-tutorials/hardhat-config-for-subtensor-evm.md b/docs/evm-tutorials/hardhat-config-for-subtensor-evm.md index 0cca194579..6443faff71 100644 --- a/docs/evm-tutorials/hardhat-config-for-subtensor-evm.md +++ b/docs/evm-tutorials/hardhat-config-for-subtensor-evm.md @@ -1,11 +1,11 @@ --- -title: "Hardhat Configuration for Subtensor EVM" +title: "Configuring Hardhat" --- import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; -# Hardhat Configuration for Subtensor EVM +# Configuring Hardhat You can use [Hardhat](https://hardhat.org/) development environment for the EVM feature on subtensor. The Hardhat networks can be configured using the `hardhat.config.ts` file, as shown below. diff --git a/docs/evm-tutorials/index.md b/docs/evm-tutorials/index.md index d11c912725..e1f882a2b1 100644 --- a/docs/evm-tutorials/index.md +++ b/docs/evm-tutorials/index.md @@ -1,5 +1,5 @@ --- -title: "EVM smart contracts on Bittensor" +title: "Bittensor EVM Smart Contracts" --- import ThemedImage from '@theme/ThemedImage'; @@ -23,49 +23,78 @@ import { BiSolidNetworkChart } from "react-icons/bi"; import { FaMoneyBillTransfer } from "react-icons/fa6"; import { GrStakeholder } from "react-icons/gr"; -# EVM smart contracts on Bittensor +# Bittensor EVM Smart Contracts -Full Ethereum virtual machine (EVM) compatibility is now available on subtensor (the blockchain in Bittensor). This allows users to: +A full ethereum virtual machine (EVM) runtime operates as an application layer on top of the Bittensor blockchain (Subtensor). This allows users to: -- Deploy most EVM smart contracts on subtensor without changing the code -- Interact with deployed smart contracts on the subtensor blockchain -- Access standard Ethereum JSON-RPC methods from this EVM compatibility layer on [Subtensor](https://github.com/opentensor/subtensor), Bittensor's substrate blockchain. +- deploy most EVM smart contracts on subtensor without changing the code, +- interact with deployed smart contracts on the subtensor blockchain, and +- access standard Ethereum JSON-RPC methods. -## Before you proceed +:::info +Bittensor EVM smart contracts are executed solely on the **Bittensor blockchain, _not_ on the Ethereum blockchain.** +::: -Before you proceed to use EVM on subtensor, make a note of the following: +See: -1. **EVM smart contract executes on subtensor**: The EVM feature allows the subtensor blockchain to execute Ethereum-compatible smart contracts. Note that all operations performed by this new subtensor EVM feature are executed solely on the subtensor blockchain, not on the Ethereum blockchain. -2. **1 TAO = 1e18 on subtensor EVM**: While working with the subtensor EVM, 1 TAO should be written as 1 followed by 18 zeroes, i.e., 1e18. See this code example: [https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js#L58](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js#L58). +- [Examples and Precompiles](./examples.md) +- [EVM on Testnet](./evm-testnet-with-metamask-wallet.md) +- [EVM on Local Chain](./evm-localnet-with-metamask-wallet.md) +- [EVM on Mainnet](./evm-mainnet-with-metamask-wallet.md) +- [Opentensor Foundation Blogpost: EVM on Bittensor](https://blog.bittensor.com/evm-on-bittensor-draft-6f323e69aff7) -Run the below tutorials to learn how to use the EVM feature on the Bittensor blockchain. +## EVM and Subtensor wallets on the Bittensor blockchian - - - - - +Bittensor wallets are based on Polkadot-style ss58 addresses, whereas Ethereum uses h160 addresses. + +The holder of a private key for an ss58 address based on the corresponding public key can sign transactions on any Bittensor chain for that address. Anyone who creates key-pairs using `btcli wallet`, for example, holds the private key and the corresponding seed phrase, and hence can sign Bittensor transactions for that wallet. + +Similarly, creating an Ethereum wallet gives you control of the h160 private key for the corresponding public key. + +:::info +You can easily [convert an h160 address to an ss58 address](./convert-h160-to-ss58.md), or vice versa, but this does _not_ yield the corresponding private key. This means that if you create a wallet in Bittensor, you will not be able to sign Ethereum contracts with it, nor versa. +::: + +Hence, in the context of Bittensor EVM we can distinguish between: + +- 'Bittensor wallets': created using the Bittensor tool chain and therefore able to sign transactions using Bittensor transaction clients (BTCLI and the Bittensor SDK), but not EVM smart contracts, on the Bittensor blockchain. +- 'EVM wallets': created using an EVM client such as MetaMask and therefore able to sign EVM smart contracts, but not Subtensor extrinsics, on the Bittensor blockchain. + +## Ethereum vs Bittensor EVM smart contract runtime + +On the Ethereum network, nodes such as full nodes, validator nodes and archive nodes run the Ethereum Virtual Environment (EVM) run-time environment. Smart contracts operate under this EVM. See the below high-level diagram. + +:::info +Note that all operations performed by Bittensor EVM are executed solely on the Bittensor blockchain, not on the Ethereum blockchain. +::: + + + + + + + + + + body='Get started by installing dependencies first.' /> + + + - As the function parameter indicates, `amount` in `addStake` and `removeStake` are specified in TAO $\tau$. + - That when transferring liquidity to the contract, `msg.value` is in denominations of 1/1e18 TAO $\tau$ . The staking precompile, however, expects RAO, 1/1e9 TAO $\tau$. You must convert before calling it: **uint256 amount = msg.value / 1e9**. diff --git a/docs/evm-tutorials/subnet-precompile.md b/docs/evm-tutorials/subnet-precompile.md new file mode 100644 index 0000000000..a3344fdc92 --- /dev/null +++ b/docs/evm-tutorials/subnet-precompile.md @@ -0,0 +1,1107 @@ +--- +title: "Subnet Precompile" +--- + +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Subnet Precompile + +This precompile allows you to interact with Bittensor subnets through EVM smart contracts, affording functionality for registering networks, viewing and setting network parameters, and querying network state. + +This page: + +- described the precompile's [available functions](#available-functions) on the precompile +- demonstrates the precompile's usage with [example scripts](#example-scripts). + +The subnet precompile is available at address `0x803` (2051 in decimal). + +View the [source on GitHub](https://github.com/opentensor/subtensor/blob/main/precompiles/src/subnet.rs) + +:::info permissions +Subnet operations have distinct requirements! + +- Creating a subnet, i.e. [`registerNetwork`,](#registernetwork) requires a coldkey with sufficient TAO to cover the current burn cost. + + See [burn cost for subnet creation](../local-build/create-subnet#subnet-creation-cost). + +- Setting subnet hyperparameters requires the private key for the coldkey that owns the subnet (the one that created it, unless this has been transferred). + +::: + +## Available Functions + +The subnet precompile provides comprehensive functionality for subnet management and configuration. All functions are categorized below: + +### Network Registration + +#### `registerNetwork` + +Create/register a new subnet, without setting identity information. + +**Parameters:** + +- `hotkey` (bytes32): The hotkey (32 bytes) that will own the network + +**Returns:** + +- None (payable function) + +**Description:** +Registers a new subnet on the Bittensor network. The caller becomes the subnet owner and can manage subnet parameters. + +#### `registerNetworkWithIdentity` + +Registers a new subnet with detailed identity information. + +**Parameters:** + +- `hotkey` (bytes32): The hotkey that will own the network +- `subnetName` (string): Name of the subnet (max 256 chars) +- `githubRepo` (string): GitHub repository URL (max 1024 chars) +- `subnetContact` (string): Contact information (max 1024 chars) +- `subnetUrl` (string): Subnet website URL (max 1024 chars) +- `discord` (string): Discord server invite (max 256 chars) +- `description` (string): Subnet description (max 1024 chars) +- `additional` (string): Additional information (max 1024 chars) + +**Returns:** + +- None (payable function) + +**Description:** +Registers a new subnet with comprehensive identity metadata that helps users understand the subnet's purpose and how to interact with it. + +### Rate Limiting + +See [Rate Limits in Bittensor](../learn/chain-rate-limits.md). + +#### `getServingRateLimit` + +Gets the serving rate limit for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The serving rate limit value + +#### `setServingRateLimit` + +Sets the serving rate limit for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `servingRateLimit` (uint64): The new serving rate limit value + +**Returns:** + +- None (payable function) + +### Difficulty Management + +#### `getMinDifficulty` + +Gets the minimum difficulty for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The minimum difficulty value + +#### `setMinDifficulty` + +Sets the minimum difficulty for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `minDifficulty` (uint64): The new minimum difficulty value + +**Returns:** + +- None (payable function) + +#### `getMaxDifficulty` + +Gets the maximum difficulty for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The maximum difficulty value + +#### `setMaxDifficulty` + +Sets the maximum difficulty for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `maxDifficulty` (uint64): The new maximum difficulty value + +**Returns:** + +- None (payable function) + +#### `getDifficulty` + +Gets the current difficulty for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The current difficulty value + +#### `setDifficulty` + +Sets the current difficulty for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `difficulty` (uint64): The new difficulty value + +**Returns:** + +- None (payable function) + +### Weight Management + +#### `getWeightsVersionKey` + +Gets the weights version key for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The weights version key value + +#### `setWeightsVersionKey` + +Sets the weights version key for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `weightsVersionKey` (uint64): The new weights version key value + +**Returns:** + +- None (payable function) + +#### `getWeightsSetRateLimit` + +Gets the weights set rate limit for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The weights set rate limit value + +#### `setWeightsSetRateLimit` ⚠️ **DEPRECATED** + +Sets the weights set rate limit for a subnet. **This function is deprecated. Subnet owners cannot set weight setting rate limits.** + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `weightsSetRateLimit` (uint64): The weights set rate limit value (ignored) + +**Returns:** + +- None (payable function) + +**Description:** +This function still exists for backward compatibility but performs no operation and returns successfully. + +#### `getMaxWeightLimit` + +Gets the maximum weight limit for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint16`: The maximum weight limit value + +#### `setMaxWeightLimit` + +Sets the maximum weight limit for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `maxWeightLimit` (uint16): The new maximum weight limit value + +**Returns:** + +- None (payable function) + +#### `getMinAllowedWeights` + +Gets the minimum allowed weights for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint16`: The minimum allowed weights value + +#### `setMinAllowedWeights` + +Sets the minimum allowed weights for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `minAllowedWeights` (uint16): The new minimum allowed weights value + +**Returns:** + +- None (payable function) + +### Consensus Parameters + +#### `getAdjustmentAlpha` + +Gets the adjustment alpha parameter for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The adjustment alpha value + +#### `setAdjustmentAlpha` + +Sets the adjustment alpha parameter for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `adjustmentAlpha` (uint64): The new adjustment alpha value + +**Returns:** + +- None (payable function) + +#### `getKappa` + +Gets the kappa parameter for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint16`: The kappa value + +#### `setKappa` + +Sets the kappa parameter for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `kappa` (uint16): The new kappa value + +**Returns:** + +- None (payable function) + +#### `getRho` + +Gets the rho parameter for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint16`: The rho value + +#### `setRho` + +Sets the rho parameter for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `rho` (uint16): The new rho value + +**Returns:** + +- None (payable function) + +#### `getAlphaSigmoidSteepness` + +Gets the alpha sigmoid steepness parameter for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint16`: The alpha sigmoid steepness value + +#### `setAlphaSigmoidSteepness` + +Sets the alpha sigmoid steepness parameter for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `steepness` (uint16): The new alpha sigmoid steepness value + +**Returns:** + +- None (payable function) + +#### `getAlphaValues` + +Gets the alpha low and high values for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint16`: The alpha low value +- `uint16`: The alpha high value + +#### `setAlphaValues` + +Sets the alpha low and high values for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `alphaLow` (uint16): The new alpha low value +- `alphaHigh` (uint16): The new alpha high value + +**Returns:** + +- None (payable function) + +### Network Activity + +#### `getImmunityPeriod` + +Gets the immunity period for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint16`: The immunity period value + +#### `setImmunityPeriod` + +Sets the immunity period for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `immunityPeriod` (uint16): The new immunity period value + +**Returns:** + +- None (payable function) + +#### `getActivityCutoff` + +Gets the activity cutoff for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint16`: The activity cutoff value + +#### `setActivityCutoff` + +Sets the activity cutoff for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `activityCutoff` (uint16): The new activity cutoff value + +**Returns:** + +- None (payable function) + +### Registration Control + +#### `getNetworkRegistrationAllowed` + +Gets whether network registration is allowed for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `bool`: Whether network registration is allowed + +#### `setNetworkRegistrationAllowed` + +Sets whether network registration is allowed for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `registrationAllowed` (bool): Whether to allow network registration + +**Returns:** + +- None (payable function) + +#### `getNetworkPowRegistrationAllowed` + +Gets whether PoW registration is allowed for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `bool`: Whether PoW registration is allowed + +#### `setNetworkPowRegistrationAllowed` + +Sets whether PoW registration is allowed for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `registrationAllowed` (bool): Whether to allow PoW registration + +**Returns:** + +- None (payable function) + +### Burn Management + +#### `getMinBurn` + +Gets the minimum burn amount for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The minimum burn amount + +#### `setMinBurn` ⚠️ **DEPRECATED** + +Sets the minimum burn amount for a subnet. **This function is deprecated. Subnet owners cannot set the minimum burn anymore.** + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `minBurn` (uint64): The minimum burn amount (ignored) + +**Returns:** + +- None (payable function) + +**Description:** +This function still exists for backward compatibility but performs no operation and returns successfully. + +#### `getMaxBurn` + +Gets the maximum burn amount for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The maximum burn amount + +#### `setMaxBurn` ⚠️ **DEPRECATED** + +Sets the maximum burn amount for a subnet. **This function is deprecated. Subnet owners cannot set the maximum burn anymore.** + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `maxBurn` (uint64): The maximum burn amount (ignored) + +**Returns:** + +- None (payable function) + +**Description:** +This function still exists for backward compatibility but performs no operation and returns successfully. + +### Bonds and Moving Averages + +#### `getBondsMovingAverage` + +Gets the bonds moving average for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The bonds moving average value + +#### `setBondsMovingAverage` + +Sets the bonds moving average for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `bondsMovingAverage` (uint64): The new bonds moving average value + +**Returns:** + +- None (payable function) + +### Feature Toggles + +#### `getCommitRevealWeightsEnabled` + +Gets whether commit-reveal weights are enabled for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `bool`: Whether commit-reveal weights are enabled + +#### `setCommitRevealWeightsEnabled` + +Sets whether commit-reveal weights are enabled for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `enabled` (bool): Whether to enable commit-reveal weights + +**Returns:** + +- None (payable function) + +#### `getCommitRevealWeightsInterval` + +Gets the commit-reveal weights interval for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `uint64`: The commit-reveal weights interval value + +#### `setCommitRevealWeightsInterval` + +Sets the commit-reveal weights interval for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `interval` (uint64): The new commit-reveal weights interval value + +**Returns:** + +- None (payable function) + +#### `getLiquidAlphaEnabled` + +Gets whether liquid alpha is enabled for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `bool`: Whether liquid alpha is enabled + +#### `setLiquidAlphaEnabled` + +Sets whether liquid alpha is enabled for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `enabled` (bool): Whether to enable liquid alpha + +**Returns:** + +- None (payable function) + +#### `getYuma3Enabled` + +Gets whether Yuma3 consensus is enabled for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID + +**Returns:** + +- `bool`: Whether Yuma3 consensus is enabled + +#### `setYuma3Enabled` + +Sets whether Yuma3 consensus is enabled for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `enabled` (bool): Whether to enable Yuma3 consensus + +**Returns:** + +- None (payable function) + +### Transfer Control + +#### `toggleTransfers` + +Toggles transfers on/off for a subnet. + +**Parameters:** + +- `netuid` (uint16): The subnetwork ID +- `toggle` (bool): Whether to enable or disable transfers + +**Returns:** + +- None (payable function) + +## Example Scripts + +[Example source on GitHub](https://github.com/opentensor/evm-bittensor/blob/main/examples/subnet.js) + +### Javascript + +```js +const { ethers, assert } = require("ethers"); +const { ApiPromise, WsProvider, Keyring } = require("@polkadot/api"); +const { convertH160ToSS58 } = require("./address-mapping.js"); +const { decodeAddress } = require("@polkadot/util-crypto"); + +// PROTECT YOUR PRIVATE KEYS WELL, NEVER COMMIT THEM TO GITHUB OR SHARE WITH ANYONE +const { ethPrivateKey, subSeed, rpcUrl, wsUrl } = require("./config.js"); +const amount1TAO = BigInt("1000000000"); +// Connect to the Subtensor node +const provider = new ethers.JsonRpcProvider(rpcUrl); + +function sendTransaction(api, call, signer) { + return new Promise((resolve, reject) => { + let unsubscribed = false; + + const unsubscribe = call + .signAndSend(signer, ({ status, events, dispatchError }) => { + const safelyUnsubscribe = () => { + if (!unsubscribed) { + unsubscribed = true; + unsubscribe + .then(() => {}) + .catch((error) => console.error("Failed to unsubscribe:", error)); + } + }; + + // Check for transaction errors + if (dispatchError) { + let errout = dispatchError.toString(); + if (dispatchError.isModule) { + // for module errors, we have the section indexed, lookup + const decoded = api.registry.findMetaError(dispatchError.asModule); + const { docs, name, section } = decoded; + errout = `${name}: ${docs}`; + } + safelyUnsubscribe(); + reject(Error(errout)); + } + // Log and resolve when the transaction is included in a block + if (status.isInBlock) { + safelyUnsubscribe(); + resolve(status.asInBlock); + } + }) + .catch((error) => { + reject(error); + }); + }); +} + +// for set +const subnet_contract_abi = [ + { + inputs: [ + { + internalType: "address", + name: "initialOwner", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousOwner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "OwnershipTransferred", + type: "event", + }, + { + inputs: [ + { + internalType: "uint16", + name: "netuid", + type: "uint16", + }, + ], + name: "getHyperParameter", + outputs: [ + { + internalType: "uint64", + name: "", + type: "uint64", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "subnetName", + type: "bytes", + }, + { + internalType: "bytes", + name: "githubRepo", + type: "bytes", + }, + { + internalType: "bytes", + name: "subnetContact", + type: "bytes", + }, + ], + name: "registerNetwork", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint16", + name: "netuid", + type: "uint16", + }, + { + internalType: "uint64", + name: "value", + type: "uint64", + }, + ], + name: "setHyperParameter", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +]; + +// compile with evm version 0.8.3 +const subnet_contract_bytecode = + "0x608060405234801561001057600080fd5b50604051610e6d380380610e6d8339818101604052810190610032919061015c565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561006d57600080fd5b61007c8161008360201b60201c565b50506101ce565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050610156816101b7565b92915050565b60006020828403121561016e57600080fd5b600061017c84828501610147565b91505092915050565b600061019082610197565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6101c081610185565b81146101cb57600080fd5b50565b610c90806101dd6000396000f3fe6080604052600436106100555760003560e01c8063290212c11461005a578063715018a614610076578063786fede51461008d57806378b63cb6146100ca5780638da5cb5b146100e6578063f2fde38b14610111575b600080fd5b610074600480360381019061006f919061077b565b61013a565b005b34801561008257600080fd5b5061008b610279565b005b34801561009957600080fd5b506100b460048036038101906100af9190610812565b61028d565b6040516100c19190610a3c565b60405180910390f35b6100e460048036038101906100df919061083b565b6103df565b005b3480156100f257600080fd5b506100fb61051a565b6040516101089190610971565b60405180910390f35b34801561011d57600080fd5b5061013860048036038101906101339190610752565b610543565b005b610142610591565b60006108039050600061080373ffffffffffffffffffffffffffffffffffffffff163463290212c160e01b8787876040516024016101829392919061098c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516101ec919061095a565b60006040518083038185875af1925050503d8060008114610229576040519150601f19603f3d011682016040523d82523d6000602084013e61022e565b606091505b5050905080610272576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610269906109d8565b60405180910390fd5b5050505050565b610281610591565b61028b60006105d2565b565b600080610803905060008061080373ffffffffffffffffffffffffffffffffffffffff16637444dadc60e01b866040516024016102ca91906109f8565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610334919061095a565b6000604051808303816000865af19150503d8060008114610371576040519150601f19603f3d011682016040523d82523d6000602084013e610376565b606091505b5091509150816103bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b2906109d8565b60405180910390fd5b6000818060200190518101906103d19190610877565b9050809450505050919050565b6103e7610591565b60006108039050600061080373ffffffffffffffffffffffffffffffffffffffff1663b38e0bbe60e01b8585604051602401610424929190610a13565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161048e919061095a565b6000604051808303816000865af19150503d80600081146104cb576040519150601f19603f3d011682016040523d82523d6000602084013e6104d0565b606091505b5050905080610514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050b906109d8565b60405180910390fd5b50505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61054b610591565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561058557600080fd5b61058e816105d2565b50565b3373ffffffffffffffffffffffffffffffffffffffff166105b061051a56b73ffffffffffffffffffffffffffffffffffffffff16146105d057600080fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006106a96106a484610a7c565b610a57565b9050828152602081018484840111156106c157600080fd5b6106cc848285610b39565b509392505050565b6000813590506106e381610c15565b92915050565b600082601f8301126106fa57600080fd5b813561070a848260208601610696565b91505092915050565b60008135905061072281610c2c565b92915050565b60008135905061073781610c43565b92915050565b60008151905061074c81610c43565b92915050565b60006020828403121561076457600080fd5b6000610772848285016106d4565b91505092915050565b60008060006060848603121561079057600080fd5b600084013567ffffffffffffffff8111156107aa57600080fd5b6107b6868287016106e9565b935050602084013567ffffffffffffffff8111156107d357600080fd5b6107df868287016106e9565b925050604084013567ffffffffffffffff8111156107fc57600080fd5b610808868287016106e9565b9150509250925092565b60006020828403121561082457600080fd5b600061083284828501610713565b91505092915050565b6000806040838503121561084e57600080fd5b600061085c85828601610713565b925050602061086d85828601610728565b9150509250929050565b60006020828403121561088957600080fd5b60006108978482850161073d565b91505092915050565b6108a981610ae5565b82525050565b60006108ba82610aad565b6108c48185610ab8565b93506108d4818560208601610b48565b6108dd81610bdb565b840191505092915050565b60006108f382610aad565b6108fd8185610ac9565b935061090d818560208601610b48565b80840191505092915050565b6000610926601283610ad4565b915061093182610bec565b602082019050919050565b61094581610af7565b82525050565b61095481610b25565b82525050565b600061096682846108e8565b915081905092915050565b600060208201905061098660008301846108a0565b92915050565b600060608201905081810360008301526109a681866108af565b905081810360208301526109ba81856108af565b905081810360408301526109ce81846108af565b9050949350505050565b60006020820190506109f181610919565b9050919050565b6000602082019050610a0d600083018461093c565b92915050565b6000604082019050610a28600083018561093c565b610a35602083018461094b565b9392505050565b6000602082019050610a51600083018461094b565b92915050565b6000610a61610a72565b9050610a6d8282610b7b565b919050565b6000604051905090565b600067ffffffffffffffff821115610a9757610a96610bac565b5b610aa082610bdb565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000610af082610b05565b9050919050565b600061ffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600067ffffffffffffffff82169050919050565b82818337600083830152505050565b60005b83811015610b66578082015181840152602081019050610b4b565b83811115610b75576000848401525b50505050565b610b8482610bdb565b810181811067ffffffffffffffff82111715610ba357610ba2610bac565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f5375626e65742063616c6c206661696c65640000000000000000000000000000600082015250565b610c1e81610ae5565b8114610c2957600080fd5b50565b610c3581610af7565b8114610c4057600080fd5b50565b610c4c81610b25565b8114610c5757600080fd5b5056fea26469706673582212200e657685be0d4a155c28ec7471273753d1c625c562f268b2efdf0a8b2c7e4dbe64736f6c63430008030033"; + +// Create a signer +const privateKey = ethPrivateKey; // DO NOT HARDCODE YOUR PRIVATE KEY IN PRODUCTION +const signer = new ethers.Wallet(privateKey, provider); + +async function createSubnetGetSetParameter() { + try { + // Substrate ss58 address that will receive the transfer + const wsProvider = new WsProvider(wsUrl); + const api = await ApiPromise.create({ provider: wsProvider }); + const keyring = new Keyring({ type: "sr25519" }); + const account = keyring.addFromUri(subSeed); // Your Substrate address private key/seed + + // Destination address can be replaced with any ss58 address here: + const destinationAddress = account.address; + + // Get the substrate address public key + const pubk = decodeAddress(destinationAddress); + const hex = Array.from(pubk, (byte) => + byte.toString(16).padStart(2, "0") + ).join(""); + + const signer = new ethers.Wallet(ethPrivateKey, provider); + + const ss58mirror = convertH160ToSS58(signer.address); + let txSudoSetBalance = api.tx.sudo.sudo( + api.tx.balances.forceSetBalance(ss58mirror, BigInt(1e18).toString()) + ); + await sendTransaction(api, txSudoSetBalance, account); + + const txSudoSetWhitelist = api.tx.sudo.sudo( + api.tx.evm.setWhitelist([signer.address]) + ); + + await sendTransaction(api, txSudoSetWhitelist, account); + + const contractFactory = new ethers.ContractFactory( + subnet_contract_abi, + subnet_contract_bytecode, + signer + ); + + const subnet_contract = await contractFactory.deploy(signer.address); + await subnet_contract.waitForDeployment(); + + console.log("deployed contract address: ", subnet_contract.target); + + txSudoSetBalance = api.tx.sudo.sudo( + api.tx.balances.forceSetBalance( + convertH160ToSS58(subnet_contract.target), + BigInt(1e16).toString() + ) + ); + await sendTransaction(api, txSudoSetBalance, account); + + let totalNetwork = Number(await api.query.subtensorModule.totalNetworks()); + console.log("total networks is ", totalNetwork); + + // there are predefined network 0 and 3. + let netuid; + if (totalNetwork > 3) { + netuid = totalNetwork; + } else { + netuid = totalNetwork - 1; + } + + const encoder = new TextEncoder(); + + let tx = await subnet_contract.registerNetwork( + encoder.encode("name"), + encoder.encode("repo"), + encoder.encode("contact") + ); + await tx.wait(); + + // the network owner is the deployed contract, not the signer + const networkOwner = ( + await api.query.subtensorModule.subnetOwner(netuid) + ).toHuman(); + console.log("networkOwner is ", networkOwner); + + // Note: This example uses setHyperParameter which calls setServingRateLimit + // Some other functions like setMinBurn, setMaxBurn, setWeightsSetRateLimit are deprecated + tx = await subnet_contract.setHyperParameter(netuid, 255); + await tx.wait(); + + // get parameter from chain + let parameter = Number( + await api.query.subtensorModule.servingRateLimit(netuid) + ); + + assert(parameter == 255); + + // get paramter from contract + parameter = await subnet_contract.getHyperParameter(netuid); + + // check total networks after registration + console.log( + "total networks is ", + (await api.query.subtensorModule.totalNetworks()).toHuman() + ); + + process.exit(0); + } catch (error) { + console.error("Error:", error); + process.exit(0); + } +} + +async function main() { + await createSubnetGetSetParameter(); +} + +main().catch(console.error); +``` + +### Solidity + +[Example source on GitHub](https://github.com/opentensor/evm-bittensor/blob/main/solidity/subnet.sol) + +```sol +// SPDX-License-Identifier: GPL-3.0 +// +// This example demonstrates calling of ISubnet precompile +// from another smart contract + +pragma solidity ^0.8.3; +import "@openzeppelin/contracts/access/Ownable.sol"; + +address constant ISUBTENSOR_SUBNET_ADDRESS = 0x0000000000000000000000000000000000000803; + +interface ISubnet { + /// Registers a new network without specifying details. + // function registerNetwork() external payable; + /// Registers a new network with specified subnet name, GitHub repository, and contact information. + function registerNetwork( + bytes memory subnetName, + bytes memory githubRepo, + bytes memory subnetContact + ) external payable; + + function getServingRateLimit(uint16 netuid) external view returns (uint64); + + function setServingRateLimit( + uint16 netuid, + uint64 servingRateLimit + ) external payable; +} + +contract Subnet is Ownable { + constructor(address initialOwner) Ownable(initialOwner) {} + + function registerNetwork( + bytes memory subnetName, + bytes memory githubRepo, + bytes memory subnetContact + ) external payable onlyOwner { + ISubnet subnetPrecompile = ISubnet(ISUBTENSOR_SUBNET_ADDRESS); + (bool success, ) = ISUBTENSOR_SUBNET_ADDRESS.call{value: msg.value}( + abi.encodeWithSelector( + subnetPrecompile.registerNetwork.selector, + subnetName, + githubRepo, + subnetContact + ) + ); + require(success, "Subnet call failed"); + } + + function setHyperParameter( + uint16 netuid, + uint64 value + ) external payable onlyOwner { + ISubnet subnetPrecompile = ISubnet(ISUBTENSOR_SUBNET_ADDRESS); + (bool success, ) = ISUBTENSOR_SUBNET_ADDRESS.call( + abi.encodeWithSelector( + subnetPrecompile.setServingRateLimit.selector, + netuid, + value + ) + ); + require(success, "Subnet call failed"); + } + + function getHyperParameter(uint16 netuid) public returns (uint64) { + ISubnet subnetPrecompile = ISubnet(ISUBTENSOR_SUBNET_ADDRESS); + (bool success, bytes memory data) = ISUBTENSOR_SUBNET_ADDRESS.call( + abi.encodeWithSelector( + subnetPrecompile.getServingRateLimit.selector, + netuid + ) + ); + require(success, "Subnet call failed"); + + uint64 value = abi.decode(data, (uint64)); + return value; + } +} + +``` diff --git a/docs/evm-tutorials/subtensor-networks.md b/docs/evm-tutorials/subtensor-networks.md index b9947cb97c..6178ef3d8a 100644 --- a/docs/evm-tutorials/subtensor-networks.md +++ b/docs/evm-tutorials/subtensor-networks.md @@ -1,11 +1,11 @@ --- -title: "Subtensor Networks" +title: "EVM Network Details" --- import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; -# Subtensor Networks +# EVM Network Details | DESCRIPTION | MAINNET | TESTNET | LOCALNET | |:---------------------|:------------------------------------|:-------------------------------------|:-------------------------| diff --git a/docs/evm-tutorials/transfer-between-two-h160-accounts.md b/docs/evm-tutorials/transfer-between-two-h160-accounts.md index 9a1c3151ca..87eec58d3a 100644 --- a/docs/evm-tutorials/transfer-between-two-h160-accounts.md +++ b/docs/evm-tutorials/transfer-between-two-h160-accounts.md @@ -31,7 +31,11 @@ You must run either [EVM Localnet with Metamask Wallet](./evm-localnet-with-meta 3. Configure the amount to be sent. In this example we are using large numbers so that the result is visible in Metamask: Because Metamask doesn't respect decimals of 9 and always defaults to 18 decimals. In production environment 0.1 TAO will match to "100000000000" (10^8), while for this demonstration we have to use "100000000000000000" (10^17), which will appear as "0.1 TAO" in Metamask, but will actually be equal to 100000000 TAO (10^8 TAO). :::tip 1 TAO = 1e18 on subtensor EVM - While working with the subtensor EVM, 1 TAO should be written as 1 followed by 18 zeroes, i.e., 1e18. Also see this code example: [https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js#L58](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js#L58). + + In Bittensor EVM, 1 TAO should be written as $1e18$ + + For [example](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js#L58): `const value = BigInt(0.5 * 1e18).toString();` + ::: ```js diff --git a/docs/evm-tutorials/transfer-from-metamask-to-ss58.md b/docs/evm-tutorials/transfer-from-metamask-to-ss58.md index 6ff2464db2..47fd6942a5 100644 --- a/docs/evm-tutorials/transfer-from-metamask-to-ss58.md +++ b/docs/evm-tutorials/transfer-from-metamask-to-ss58.md @@ -1,135 +1,152 @@ --- -title: "Transfer from Metamask to SS58 address" +title: "Transfer TAO from Metamask to SS58 Address" --- + import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; -# Transfer from Metamask to SS58 address +# Transfer TAO from Metamask to SS58 Address + +In this tutorial you will learn how to transfer TAO from your Metamask wallet to your Bittensor SS58 address for a coldkey (wallet) or a hotkey. There are two different options: -In this tutorial you will learn how to transfer TAO from your Metamask wallet to your Bittensor SS58 address for a coldkey (wallet) or a hotkey. You will learn how to do this via two different methods: +- [**Option 1:** Transfer using a precompiled contract](#option-1-transfer-using-a-precompiled-contract). +- [**Option 2:** Transfer using the `withdraw` extrinsic in the `evm` pallet in subtensor blockchain](#option-2-transfer-using-the-withdraw-extrinsic-in-the-subtensor-evm-pallet). -- **Method 1:** Transfer using a precompiled contract. -- **Method 2:** Transfer using the `withdraw` extrinsic in the `evm` pallet in subtensor blockchain. +## Prerequisites -## Prerequisite +- **Node.js** (v16 or later recommended) +- **npm** or **yarn** +- [Clone and install the Bittensor EVM examples repo](./install.md) +- [Get set up for using EVM wallet on testnet](./evm-testnet-with-metamask-wallet) -:::danger stop, did you set up your Metamask wallet for EVM? -You must run [EVM Testnet with Metamask Wallet](./evm-testnet-with-metamask-wallet.md) tutorial before you can run this tutorial. +## Option 1: Transfer using a Precompiled Contract + +:::tip +This is the best option for most users. You do NOT need the private key or seed for your SS58 address. ::: -## Method 1: Transfer using a precompiled contract +This option uses a precompiled contract to transfer TAO from your Metamask wallet to any SS58 address (coldkey or hotkey). -The private key or the seed for your SS58 is **not required** for this method. +### Configure the destination address -This step will transfer 0.5 TAO to your `ss58` destination address specified in the [`withdraw.js`](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js) file. Look for the following lines in this file: +Open [`withdraw.js`](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js) in the EVM-Bittensor repo. Find the following line: -```javascript +```js // Destination address can be replaced with any ss58 address here: const destinationAddress = account.address; ``` -and provide your `ss58` destination address as shown below: +Replace it with your own SS58 address: -```javascript +```js const destinationAddress = "5HgU7B3xfSfisR1A7wDMt7FHX5Uizj6xtWWHwhwJMZSrdN7y"; ``` -:::danger Stop. Did you install the dependencies? -Before you proceed, make sure you finished the [Install](./install.md) step. -::: - -Next, navigate to the `examples` directory of the EVM-Bittensor repo: +### Run the transfer script - ```bash - cd examples - ``` -Run: +Run the `transfer.js` script by navigating to the `examples` folder and running the following command: ```bash node transfer.js ``` -:::tip 1 TAO = 1e18 on subtensor EVM -While working with the subtensor EVM, 1 TAO should be written as 1 followed by 18 zeroes, i.e., 1e18. See this code example: [https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js#L58](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js#L58). +:::tip 1 TAO = 1e18 +In Bittensor EVM, 1 TAO is written as `1e18` (just like on Ethereum). For example, to send 0.5 TAO: + +```js +const value = BigInt(0.5 * 1e18).toString(); +``` + ::: -Then, run: +### Run the withdraw script + +Run the `withdraw.js` script by navigating to the `examples` folder and running the following command: ```bash node withdraw.js ``` -You will see the output similar to below, indicating a successful transfer of TAO from your Metamask account to your `ss58` destination address: +You should see output similar to: ```bash showLineNumbers node withdraw.js 2024-10-07 15:34:58 REGISTRY: Unknown signed extensions SubtensorSignedExtension, CommitmentsSignedExtension found, treating them as no-effect -2024-10-07 15:34:58 API/INIT: RPC methods not decorated: chainHead_v1_body, chainHead_v1_call, chainHead_v1_continue, chainHead_v1_follow, chainHead_v1_header, chainHead_v1_stopOperation, chainHead_v1_storage, chainHead_v1_unfollow, chainHead_v1_unpin, chainSpec_v1_chainName, chainSpec_v1_genesisHash, chainSpec_v1_properties, debug_getBadBlocks, debug_getRawBlock, debug_getRawHeader, debug_getRawReceipts, debug_getRawTransaction, delegateInfo_getDelegate, delegateInfo_getDelegated, delegateInfo_getDelegates, eth_getBlockReceipts, neuronInfo_getNeuron, neuronInfo_getNeuronLite, neuronInfo_getNeurons, neuronInfo_getNeuronsLite, subnetInfo_getLockCost, subnetInfo_getSubnetHyperparams, subnetInfo_getSubnetInfo, subnetInfo_getSubnetInfo_v2, subnetInfo_getSubnetsInf_v2, subnetInfo_getSubnetsInfo, transactionWatch_v1_submitAndWatch, transactionWatch_v1_unwatch, transaction_v1_broadcast, transaction_v1_stop -2024-10-07 15:34:58 API/INIT: node-subtensor/302: Not decorating unknown runtime apis: 0x42e62be4a39e5b60/1, 0x806df4ccaa9ed485/1, 0x8375104b299b74c5/1, 0x5d1fbfbe852f2807/1, 0xc6886e2f8e598b0a/1 +... Sending balance to ss58 address: 5HgU7B3xfSfisR1A7wDMt7FHX5Uizj6xtWWHwhwJMZSrdN7y pubk = f873b72b75b9029397edceaa04cf08cc97909c8b6304f2ccc3593641bf92e97c -Transaction response: ContractTransactionResponse { - provider: JsonRpcProvider {}, - blockNumber: null, - blockHash: null, - index: undefined, - hash: '0x4f3bde9e678d7307f2c07dd3212d6920db8e2af8ade052a823b3ad1f28ddc221', - type: 2, - to: '0x0000000000000000000000000000000000000800', - from: '0x709615c655B24919F48B365D292521EFcC74467B', - nonce: 0, - gasLimit: 21576n, - gasPrice: undefined, - maxPriorityFeePerGas: 0n, - maxFeePerGas: 20000000000n, - maxFeePerBlobGas: null, - data: '0xcd6f4eb1f873b72b75b9029397edceaa04cf08cc97909c8b6304f2ccc3593641bf92e97c', - value: 500000000000000000n, - chainId: 945n, - signature: Signature { r: "0xc8cf1d54513eb26ee13ca8e001201e918d50593ce6efd4ceee6645ec1879f183", s: "0x6594fe686ecac6131b536b9ff5277f40da1d12ab6c2a269693029c58cef8417d", yParity: 0, networkV: null }, - accessList: [], - blobVersionedHashes: null -} +Transaction response: ContractTransactionResponse { ... } Transaction confirmed. ``` -In the above example, a coldkey `ss58` address `5HgU7B3xfSfisR1A7wDMt7FHX5Uizj6xtWWHwhwJMZSrdN7y` (line 5 in the above log) is used as a destination address. The Metamask wallet address used is: `0x709615c655B24919F48B365D292521EFcC74467B` (line 15 in the above log). +:::info +The `ss58` address is your destination (coldkey or hotkey). The `from` address is your Metamask wallet. +::: + +### Check your SS58 balance -Finally, use the below `btcli` command to check the balance of your `ss58` address (the below `--ss58` option is supported in BTCLI 8.2.0 or later versions): +Use the Bittensor CLI to check your new balance: ```bash btcli wallet balance --ss58 5HgU7B3xfSfisR1A7wDMt7FHX5Uizj6xtWWHwhwJMZSrdN7y ``` -## Method 2: Transfer using `withdraw` extrinsic in subtensor `evm` pallet +## Option 2: Transfer using the `withdraw` Extrinsic in the Subtensor EVM Pallet + +:::tip +This option is best for advanced users. You WILL need the private key for your SS58 address. +::: + +This option uses the `withdraw` extrinsic in the EVM pallet, allowing you to transfer from an EVM address to an SS58 address using Polkadot.js Apps. + +### Copy your SS58 address + +For example: `5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty`. You will need the private key for this address set up in the Polkadot.js extension. + +### Edit the destination in the script + +Open [`withdraw-address.js`](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw-address.js) and set your SS58 address: + +```js +const ss58Address = ""; +``` + +### Run the withdraw-address script + +Run the `withdraw-address.js` script by navigating to the `examples` folder and running the following command: + +```bash +node withdraw-address.js +``` + +### Copy the "Ethereum mirror" output address + +The script will output an "Ethereum mirror" address. Copy this address. + +### Transfer TAO to the mirror address using Metamask -You will need the private key for your SS58 for this method. +- Open Metamask and send the desired amount of TAO to the mirror address. +- If you restarted the network, clear Metamask's activity tab data: **Settings > Advanced > Clear activity tab data**. -1. Copy your `ss58` address (for example: `5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty`). You need the private key for this address setup in Polkadot JS extension. -2. Paste it into `ss58Address` in main function in [`withdraw-address.js`](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw-address.js) script. +### Ensure your destination address is funded -3. Next, navigate to the `examples` directory of the EVM-Bittensor repo: +Make sure the destination address has enough TAO to pay for transaction fees. - ```bash - cd examples - ``` +### Open the Extrinsics page in Polkadot.js Apps -4. Run: +[Polkadot.js Apps Extrinsics](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftest.chain.opentensor.ai%3A443#/extrinsics) - ```bash - node withdraw-address.js - ``` +### Submit the withdraw extrinsic -5. Copy the "Ethereum mirror:" output address. -6. Transfer the amount to this address that you wish to transfer using Metamask. Make sure to clear activity tab data if you restarted the network previously: **Settings** > **Advanced** > **Clear activity tab data**. -7. Make sure your destination address is funded to run a transaction. -8. Open the **Extrisics** section in Polkadot JS app: [https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftest.chain.opentensor.ai%3A443#/extrinsics](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftest.chain.opentensor.ai%3A443#/extrinsics). -9. Select `evm` pallet and `withdraw` extrinsic. -10. Paste the "Ethereum mirror" output address into address field. -11. Put the amount you are transferring into amount field. Note that Metamask balances are by 10^9 lower than Polkadot Apps UI balances because Metamask will not respect 10^9 decimals for native currency before we have a corresponding PR to https://github.com/ethereum-lists merged. -12. Submit the transaction. -13. Finally, use the below `btcli` command to check the balance of your `ss58` address (the below `--ss58` option is supported in BTCLI 8.2.0 or later versions): +- Select the `evm` pallet and `withdraw` extrinsic. +- Paste the "Ethereum mirror" address into the address field. +- Enter the amount you are transferring. +- Note: Metamask balances are by 10^9 lower than Polkadot Apps UI balances (Metamask does not respect 10^9 decimals for native currency). - ```bash - btcli wallet balance --ss58 - ``` +### Submit the transaction + +### Check your SS58 balance + +```bash +btcli wallet balance --ss58 +``` diff --git a/docs/evm-tutorials/transfer-from-metamask-to-ss58EDGE.md b/docs/evm-tutorials/transfer-from-metamask-to-ss58EDGE.md new file mode 100644 index 0000000000..1774226b93 --- /dev/null +++ b/docs/evm-tutorials/transfer-from-metamask-to-ss58EDGE.md @@ -0,0 +1,128 @@ +--- +title: "Transfer from Metamask to SS58 address" +--- +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Transfer from Metamask to SS58 address + +In this tutorial you will learn how to transfer TAO from your Metamask wallet to your Bittensor SS58 address for a coldkey (wallet) or a hotkey. You will learn how to do this via two different methods: + +- **Method 1:** Transfer using a precompiled contract. +- **Method 2:** Transfer using the `withdraw` extrinsic in the `evm` pallet in subtensor blockchain. + +## Prerequisite + +:::danger stop, did you set up your Metamask wallet for EVM? +You must run [EVM Testnet with Metamask Wallet](./evm-testnet-with-metamask-wallet.md) tutorial before you can run this tutorial. +::: + +## Method 1: Transfer using a precompiled contract + +The private key or the seed for your SS58 is **not required** for this method. + +This step will transfer 0.5 TAO to your `ss58` destination address specified in the [`withdraw.js`](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js) file. Look for the following lines in this file: + +```javascript +// Destination address can be replaced with any ss58 address here: +const destinationAddress = account.address; +``` + +and provide your `ss58` destination address as shown below: + +```javascript +const destinationAddress = "5HgU7B3xfSfisR1A7wDMt7FHX5Uizj6xtWWHwhwJMZSrdN7y"; +``` + +Run: + +```bash +node transfer.js +``` + +:::tip +In Bittensor EVM, 1 TAO should be written as $1e18$ + +For [example](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw.js#L58): `const value = BigInt(0.5 * 1e18).toString();` +::: + +Then, run: + +```bash +node withdraw.js +``` + +You will see the output similar to below, indicating a successful transfer of TAO from your Metamask account to your `ss58` destination address: + +```bash showLineNumbers +node withdraw.js +2024-10-07 15:34:58 REGISTRY: Unknown signed extensions SubtensorSignedExtension, CommitmentsSignedExtension found, treating them as no-effect +2024-10-07 15:34:58 API/INIT: RPC methods not decorated: chainHead_v1_body, chainHead_v1_call, chainHead_v1_continue, chainHead_v1_follow, chainHead_v1_header, chainHead_v1_stopOperation, chainHead_v1_storage, chainHead_v1_unfollow, chainHead_v1_unpin, chainSpec_v1_chainName, chainSpec_v1_genesisHash, chainSpec_v1_properties, debug_getBadBlocks, debug_getRawBlock, debug_getRawHeader, debug_getRawReceipts, debug_getRawTransaction, delegateInfo_getDelegate, delegateInfo_getDelegated, delegateInfo_getDelegates, eth_getBlockReceipts, neuronInfo_getNeuron, neuronInfo_getNeuronLite, neuronInfo_getNeurons, neuronInfo_getNeuronsLite, subnetInfo_getLockCost, subnetInfo_getSubnetHyperparams, subnetInfo_getSubnetInfo, subnetInfo_getSubnetInfo_v2, subnetInfo_getSubnetsInf_v2, subnetInfo_getSubnetsInfo, transactionWatch_v1_submitAndWatch, transactionWatch_v1_unwatch, transaction_v1_broadcast, transaction_v1_stop +2024-10-07 15:34:58 API/INIT: node-subtensor/302: Not decorating unknown runtime apis: 0x42e62be4a39e5b60/1, 0x806df4ccaa9ed485/1, 0x8375104b299b74c5/1, 0x5d1fbfbe852f2807/1, 0xc6886e2f8e598b0a/1 +Sending balance to ss58 address: 5HgU7B3xfSfisR1A7wDMt7FHX5Uizj6xtWWHwhwJMZSrdN7y +pubk = f873b72b75b9029397edceaa04cf08cc97909c8b6304f2ccc3593641bf92e97c +Transaction response: ContractTransactionResponse { + provider: JsonRpcProvider {}, + blockNumber: null, + blockHash: null, + index: undefined, + hash: '0x4f3bde9e678d7307f2c07dd3212d6920db8e2af8ade052a823b3ad1f28ddc221', + type: 2, + to: '0x0000000000000000000000000000000000000800', + from: '0x709615c655B24919F48B365D292521EFcC74467B', + nonce: 0, + gasLimit: 21576n, + gasPrice: undefined, + maxPriorityFeePerGas: 0n, + maxFeePerGas: 20000000000n, + maxFeePerBlobGas: null, + data: '0xcd6f4eb1f873b72b75b9029397edceaa04cf08cc97909c8b6304f2ccc3593641bf92e97c', + value: 500000000000000000n, + chainId: 945n, + signature: Signature { r: "0xc8cf1d54513eb26ee13ca8e001201e918d50593ce6efd4ceee6645ec1879f183", s: "0x6594fe686ecac6131b536b9ff5277f40da1d12ab6c2a269693029c58cef8417d", yParity: 0, networkV: null }, + accessList: [], + blobVersionedHashes: null +} +Transaction confirmed. +``` + +In the above example, a coldkey `ss58` address `5HgU7B3xfSfisR1A7wDMt7FHX5Uizj6xtWWHwhwJMZSrdN7y` (line 5 in the above log) is used as a destination address. The Metamask wallet address used is: `0x709615c655B24919F48B365D292521EFcC74467B` (line 15 in the above log). + +Finally, use the below `btcli` command to check the balance of your `ss58` address (the below `--ss58` option is supported in BTCLI 8.2.0 or later versions): + +```bash +btcli wallet balance --ss58 5HgU7B3xfSfisR1A7wDMt7FHX5Uizj6xtWWHwhwJMZSrdN7y +``` + +## Method 2: Transfer using `withdraw` extrinsic in subtensor `evm` pallet + +You will need the private key for your SS58 for this method. + +1. Copy your `ss58` address (for example: `5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty`). You need the private key for this address setup in Polkadot JS extension. +2. Paste it into `ss58Address` in main function in [`withdraw-address.js`](https://github.com/opentensor/evm-bittensor/blob/main/examples/withdraw-address.js) script. + +3. Next, navigate to the `examples` directory of the EVM-Bittensor repo: + + ```bash + cd examples + ``` + +4. Run: + + ```bash + node withdraw-address.js + ``` + +5. Copy the "Ethereum mirror:" output address. +6. Transfer the amount to this address that you wish to transfer using Metamask. Make sure to clear activity tab data if you restarted the network previously: **Settings** > **Advanced** > **Clear activity tab data**. +7. Make sure your destination address is funded to run a transaction. +8. Open the **Extrisics** section in Polkadot JS app: [https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftest.chain.opentensor.ai%3A443#/extrinsics](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftest.chain.opentensor.ai%3A443#/extrinsics). +9. Select `evm` pallet and `withdraw` extrinsic. +10. Paste the "Ethereum mirror" output address into address field. +11. Put the amount you are transferring into amount field. Note that Metamask balances are by 10^9 lower than Polkadot Apps UI balances because Metamask will not respect 10^9 decimals for native currency before we have a corresponding PR to https://github.com/ethereum-lists merged. +12. Submit the transaction. +13. Finally, use the below `btcli` command to check the balance of your `ss58` address (the below `--ss58` option is supported in BTCLI 8.2.0 or later versions): + + ```bash + btcli wallet balance --ss58 + ``` diff --git a/docs/evm-tutorials/withdraw-from-alice.md b/docs/evm-tutorials/withdraw-from-alice.md new file mode 100644 index 0000000000..7fd9ecf975 --- /dev/null +++ b/docs/evm-tutorials/withdraw-from-alice.md @@ -0,0 +1,149 @@ +--- +title: "Withdraw TAO from Alice Account (Local Development)" +--- + +import { InstallPartial } from "./\_install.mdx"; +import { CreatePartial } from "./\_create-mm-wallet.mdx"; + +# Withdraw TAO from Alice Account (Local Development) + +Every locally deployed dev-mode blockchain comes provisioned with an 'Alice' account holding a large bag of TAO. + +This page shows how to withdraw TAO to your wallet, using a transaction that requires root permissions, and therefore is only available in local development. + +## Prerequesites + +[Deploy a Subtensor Blockchain locally](../local-build/deploy) + +## Procedure + +### Create Wallet with MetaMask + + + +### Install the EVM Examples repo + + + +### Configure your request + +The `withdraw.js` script in the `examples` folder expects your configuration to be available in config.js. +Select the local configuration options for `rpcURL` and `wsUrl`. + +:::danger +Handle your private keys with care. Do not commit them to Github. +::: + +``` +// PROTECT YOUR PRIVATE KEYS WELL, NEVER COMMIT THEM TO GITHUB OR SHARE WITH ANYONE +const ethPrivateKey = ; +const subSeed = "//Alice"; +const rpcUrlLocal = 'http://127.0.0.1:9946'; +const rpcUrlTestnet = 'https://test.chain.opentensor.ai'; +const wsUrlLocal = 'ws://127.0.0.1:9946'; +const wsUrlTestnet = 'wss://test.chain.opentensor.ai'; + +module.exports = { + ethPrivateKey, + subSeed, + rpcUrl: rpcUrlLocal, + wsUrl: wsUrlLocal, +} +``` + +### Run the script + +Run the `withdraw.js` script by navigating to the `examples` folder and running the following command: + +```bash +node withdraw.js +``` + +**Source code**: + +- [EVM examples repo](https://github.com/opentensor/evm-bittensor) + +```javascript +const { ethers } = require("ethers"); +const { ApiPromise, WsProvider, Keyring } = require("@polkadot/api"); +const { convertH160ToSS58 } = require("./address-mapping.js"); + +// PROTECT YOUR PRIVATE KEYS WELL, NEVER COMMIT THEM TO GITHUB OR SHARE WITH ANYONE +const { ethPrivateKey, subSeed, rpcUrl, wsUrl } = require("./config.js"); + +function sendTransaction(api, call, signer) { + return new Promise((resolve, reject) => { + let unsubscribed = false; + + const unsubscribe = call + .signAndSend(signer, ({ status, events, dispatchError }) => { + const safelyUnsubscribe = () => { + if (!unsubscribed) { + unsubscribed = true; + unsubscribe + .then(() => {}) + .catch((error) => console.error("Failed to unsubscribe:", error)); + } + }; + + // Check for transaction errors + if (dispatchError) { + let errout = dispatchError.toString(); + if (dispatchError.isModule) { + // for module errors, we have the section indexed, lookup + const decoded = api.registry.findMetaError(dispatchError.asModule); + const { docs, name, section } = decoded; + errout = `${name}: ${docs}`; + } + safelyUnsubscribe(); + reject(Error(errout)); + } + // Log and resolve when the transaction is included in a block + if (status.isInBlock) { + safelyUnsubscribe(); + resolve(status.asInBlock); + } + }) + .catch((error) => { + reject(error); + }); + }); +} + +async function main() { + const wsProvider = new WsProvider(wsUrl); + const api = await ApiPromise.create({ provider: wsProvider }); + const keyring = new Keyring({ type: "sr25519" }); + + const sender = keyring.addFromUri(subSeed); // Your sender's private key/seed + + // Get ethereum address that matches the private key from the secrets file + const provider = new ethers.JsonRpcProvider(rpcUrl); + const signer = new ethers.Wallet(ethPrivateKey, provider); + const recipientEthereumAddress = signer.address; + + const ss58Address = convertH160ToSS58(recipientEthereumAddress); + console.log(`Mirror: ${ss58Address}`); + // Amount to send: 1 TAO on Substrate side = 1*10^9 + const amount = "1000000000"; + + // Alice funds herself with 1M TAO + const txSudoSetBalance = api.tx.sudo.sudo( + api.tx.balances.forceSetBalance(sender.address, "1000000000000000") + ); + await sendTransaction(api, txSudoSetBalance, sender); + console.log("Balace force-set"); + + // Create a transfer transaction + const transfer = api.tx.balances.transferKeepAlive(ss58Address, amount); + + // Sign and send the transaction + await sendTransaction(api, transfer, sender); + console.log( + `Transfer sent to ${recipientEthereumAddress} (its ss58 mirror address is: ${ss58Address})` + ); + await api.disconnect(); +} + +main().catch(console.error); +``` diff --git a/docs/getting-started/install-btcli.md b/docs/getting-started/install-btcli.md index 4bd09abfcb..1b4efe7711 100644 --- a/docs/getting-started/install-btcli.md +++ b/docs/getting-started/install-btcli.md @@ -2,23 +2,33 @@ title: "Install BTCLI" --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # Install BTCLI This page contains installation details for `btcli`, the Bittensor CLI. -## Prerequisite +--- -To install `btcli`, you must have Python version 3.9-3.12 +:::warning Install from Verified Sources +Always double-check the package name and origin before installation. Use links and commands directly from our docs or official release announcements to avoid malicious lookalikes. +::: -See: https://github.com/opentensor/btcli/blob/main/setup.py#L91-L94 +## Prerequisite + +To install `btcli`, you must have Python version 3.9-3.12. See config file on [GitHub](https://github.com/opentensor/btcli/blob/main/pyproject.toml#L57-L60). ## Developer reference -For a full developer reference, see the [Bittensor CLI reference document](../btcli.md). +For a full developer reference, see the [Bittensor CLI reference document](../btcli/btcli.md). ## Install on macOS and Linux -### Install from Python Package Indexer +You can install the Bittensor CLI on macOS and Linux using any of the following methods: + + + Check for the latest release at the Python Package Index: [https://pypi.org/project/bittensor-cli/](https://pypi.org/project/bittensor-cli/). @@ -29,58 +39,81 @@ pip install bittensor-cli # Use latest or desired version ``` Verify your installation and its version by running: + ```shell btcli --version ``` + Example output: + ```console BTCLI version: 9.2.0 ``` + :::warning Update frequently! Check frequently to make sure you are using the latest version of `btcli`. ::: + + +To install the Bittensor CLI using Homebrew, run the following command in your terminal: + +```shell +brew install btcli +``` + +Next, verify your installation and its version by running: + +```shell +btcli --version +``` -### Install from source +:::warning Update frequently! +Check frequently to make sure you are using the latest version of `btcli`. +::: + + 1. Create and activate a virtual environment. - :::tip Create and activate a virtual environment + :::tip Create and activate a virtual environment - - Create Python virtual environment. Follow [this guide on python.org](https://docs.python.org/3/library/venv.html#creating-virtual-environments). + - Create Python virtual environment. Follow [this guide on python.org](https://docs.python.org/3/library/venv.html#creating-virtual-environments). - - Activate the new environment. Follow [this guide on python.org](https://docs.python.org/3/library/venv.html#how-venvs-work) - ::: - :::warning For Ubuntu-Linux users - If you are using Ubuntu-Linux, the script will prompt for `sudo` access to install all required apt-get packages. - ::: + - Activate the new environment. Follow [this guide on python.org](https://docs.python.org/3/library/venv.html#how-venvs-work) + ::: + :::warning For Ubuntu-Linux users + If you are using Ubuntu-Linux, the script will prompt for `sudo` access to install all required apt-get packages. + ::: - ```bash - python3 -m venv btcli_venv - source btcli_venv/bin/activate - ``` + ```bash + python3 -m venv btcli_venv + source btcli_venv/bin/activate + ``` 2. Clone the Bittensor CLI repo. - ```bash - git clone https://github.com/opentensor/btcli.git - ``` + ```bash + git clone https://github.com/opentensor/btcli.git + ``` 3. `cd` into `btcli` directory. - ```bash - cd btcli - ``` + ```bash + cd btcli + ``` -4. Install +4. Install + ```bash + pip3 install . + ``` - ```bash - pip3 install . - ``` + + ## Install on Windows -To install and run Bittensor SDK on Windows you must install [**WSL 2** (Windows Subsystem for Linux)](https://learn.microsoft.com/en-us/windows/wsl/about) on Windows and select [Ubuntu Linux distribution](https://github.com/ubuntu/WSL/blob/main/docs/guides/install-ubuntu-wsl2.md). +To install and run Bittensor SDK on Windows you must install [**WSL 2** (Windows Subsystem for Linux)](https://learn.microsoft.com/en-us/windows/wsl/about) on Windows and select [Ubuntu Linux distribution](https://github.com/ubuntu/WSL/blob/main/docs/guides/install-ubuntu-wsl2.md). After you installed the above, follow the same installation steps described above in [Install on macOS and Linux](#install-on-macos-and-linux). @@ -88,18 +121,19 @@ After you installed the above, follow the same installation steps described abov While wallet transactions like delegating, transfer, registering, staking can be performed on a Windows machine using WSL 2, the mining and validating operations are not recommended and are not supported on Windows machines. ::: - ## Verify the installation ```bash btcli --version ``` + which will give you the below output: ```bash BTCLI version: ``` -You will see the version number you installed in place of ``. + +You will see the version number you installed in place of ``. ## Configuration @@ -123,10 +157,12 @@ metagraph_cols: CONSENSUS: true DIVIDENDS: true EMISSION: true + GLOBAL_STAKE: true HOTKEY: true INCENTIVE: true + LOCAL_STAKE: true RANK: true - STAKE: true + STAKE_WEIGHT: true TRUST: true UID: true UPDATED: true @@ -143,3 +179,25 @@ If both `chain` and `network` config values are present in the `config.yml`, the ```bash btcli config --help ``` + +### Environment variables + +The Bittensor CLI also accepts environment variables that can change how it works: + +- `USE_TORCH` (default 0): If set to 1, will use torch instead of numpy +- `DISK_CACHE` (default 0, also settable in config): If set to 1 (or set in config), will use disk caching for various safe-cachable substrate + calls (such as block number to block hash mapping), which can speed up subsequent calls. +- `BTCLI_CONFIG_PATH` (default `~/.bittensor/config.yml`): This will set the config file location, creating if it does not exist. +- `BTCLI_DEBUG_FILE` (default `~/.bittensor/debug.txt`): The file stores the most recent's command's debug log. + +## Debugging + +BTCLI stores a debug log for every command you run. Debug logging is enabled by default if `use_cache` is on. All logs are written to `~/.bittensor/debug.txt` and overwritten after each BTCLI command. + +You can change the location with the [`BTCLI_DEBUG_FILE` environment variable](#environment-variables). + +:::info +The debug log does not contain sensitive data (such as private keys). It is intended to be shared with developers for troubleshooting. The file includes details about the executed command, configuration, and request/response interactions with the chain. +::: + +If you encounter an issue and want to preserve the log before it is overwritten, run `btcli --debug` and specify a new location to save the file. We recommend doing this first before starting your debugging with us on [Discord](https://discord.gg/bittensor) or opening an issue on [GitHub](https://github.com/opentensor/btcli/issues/new), where you can also upload your debug file. diff --git a/docs/getting-started/install-wallet-sdk.md b/docs/getting-started/install-wallet-sdk.md index 41e4811415..cd8a3225da 100644 --- a/docs/getting-started/install-wallet-sdk.md +++ b/docs/getting-started/install-wallet-sdk.md @@ -2,6 +2,12 @@ title: "Install Wallet SDK" --- +--- + +:::warning Install from Verified Sources +Always double-check the package name and origin before installation. Use links and commands directly from our docs or official release announcements to avoid malicious lookalikes. +::: + # Install Wallet SDK The Bittensor Wallet SDK is a Python interface for a powerful Rust-based Bittensor wallet functionality. You do not need to know Rust to use this Wallet SDK. However, if you want to contribute to the Rust components of this Wallet SDK, the Rust source is located in the `src` directory of [btwallet](https://github.com/opentensor/btwallet) repo. @@ -150,7 +156,7 @@ IMPORTANT: Store this mnemonic in a secure (preferable offline place), as anyone ``` -The above will create a wallet with "my_wallet_name". +The above will create a wallet with "my_wallet_name". **3. Use your own config** diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index 0731497987..b2150e6f22 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -2,17 +2,26 @@ title: "Install Bittensor SDK" --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # Install Bittensor SDK Before you can start developing, you must install Bittensor SDK and then create Bittensor wallet. +--- + +:::warning Install from Verified Sources +Always double-check the package name and origin before installation. Use links and commands directly from our docs or official release announcements to avoid malicious lookalikes. +::: + ## Supported Python versions -- bittensor (SDK): Python 3.9-3.11 (reference: https://github.com/opentensor/bittensor/blob/master/setup.py#L86-L88) -- bittensor-cli: Python 3.9-3.12 (reference: https://github.com/opentensor/btcli/blob/main/setup.py#L91-L94 ) -- bittensor-wallet: Python 3.9-3.12 (reference: https://github.com/opentensor/btwallet/blob/main/pyproject.toml#L34-L37) +- bittensor (SDK): Python 3.9-3.13 (reference: https://github.com/opentensor/bittensor/blob/master/pyproject.toml#L14) +- bittensor-cli: Python 3.9-3.13 (reference: https://github.com/opentensor/btcli/blob/main/pyproject.toml#L15 ) +- bittensor-wallet: Python 3.9-3.13 (reference: https://github.com/opentensor/btwallet/blob/main/pyproject.toml#L11) -## Upgrade +## Upgrade the Bittensor SDK If you already installed Bittensor SDK, make sure you upgrade to the latest version. Run the below command: @@ -20,154 +29,181 @@ If you already installed Bittensor SDK, make sure you upgrade to the latest vers python3 -m pip install --upgrade bittensor ``` -## Developer reference +## Install on macOS and Linux -For a full developer reference, see the [Bittensor SDK section](../bt-api-ref.md). +You can install Bittensor on your macOS or Linux machine using any one of the available options. **Make sure you verify your installation after you install**. -## Install on macOS and Linux +:::warning Rust Required on Linux +To install the Bittensor SDK on Linux, you must have Rust installed. For information on Rust installation and setup, see the [official Rust documentation](https://www.rust-lang.org/tools/install). +::: -You can install Bittensor on your local machine in either of the following ways. **Make sure you verify your installation after you install**. -- [Install using a Bash command](#install-using-a-bash-command). -- [Install from source](#install-from-source) +:::tip Create and activate a virtual environment +To avoid dependency issues while installing the Bittensor SDK, we recommend [creating](https://docs.python.org/3/library/venv.html#creating-virtual-environments) and [activating](https://docs.python.org/3/library/venv.html#how-venvs-work) a Python Virtual environment on your machine before installing the SDK. To do this, ensure you have Python3 installed on your local machine using the following command: -### Install using a Bash command +```bash +python3 --version +``` -This is the most straightforward method. It is recommended for a beginner as it will pre-install requirements like Python, if they are not already present on your machine. Copy and paste the following `bash` command into your terminal: +Then run the following command in your terminal: ```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/opentensor/bittensor/master/scripts/install.sh)" +python3 -m venv btsdk_venv +source btsdk_venv/bin/activate ``` -:::warning For Ubuntu-Linux users -If you are using Ubuntu-Linux, the script will prompt for `sudo` access to install all required apt-get packages. ::: -:::tip Create and activate a virtual environment - - Create Python virtual environment. Follow [this guide on python.org](https://docs.python.org/3/library/venv.html#creating-virtual-environments). + + + You can install Bittensor via the Python Package Index using any of the below options: - - Activate the new environment. Follow [this guide on python.org](https://docs.python.org/3/library/venv.html#how-venvs-work) -::: + - **Install SDK**: Run the below command to install Bittensor SDK in the above virtual environment. This will install `btcli` also. -### Install Python virtual environment + ```python + pip install bittensor + ``` -```bash -python3 -m venv btsdk_venv -source btsdk_venv/bin/activate -``` + - **Install SDK with `torch`**: Install Bittensor SDK with [`torch`](https://pytorch.org/docs/stable/torch.html). -### Install from source + ```python + pip install bittensor[torch] + ``` -1. Clone the Bittensor repo + If the command fails in your environment, try enclosing the argument in quotes as shown: -```bash -git clone https://github.com/opentensor/bittensor.git -``` -2. Change to the Bittensor directory: + ```python + pip install "bittensor[torch]" + ``` -```bash -cd bittensor -``` -3. Install + -- **Install SDK**: Run the below command to install Bittensor SDK in the above virtual environment. This will also install `btcli`. -```python -pip install . -``` + - **Install SDK with `cubit`**: Install Bittensor SDK with [`cubit`](https://github.com/opentensor/cubit). -- **Install SDK with `torch`**: Install Bittensor SDK with [`torch`](https://pytorch.org/docs/stable/torch.html). + 1. Install `cubit` first. See the [Install](https://github.com/opentensor/cubit?tab=readme-ov-file#install) section. **Only Python 3.9 and 3.10 versions are supported**. + 2. Then install SDK with `pip install bittensor`. - ```python - pip install bittensor[torch] - ``` - In some environments the above command may fail, in which case run the command with added quotes as shown below: + + + + This is the most straightforward method. It is recommended for a beginner as it will pre-install requirements for the Bittensor SDK like Python, if they are not already present on your machine. Copy and paste the following `bash` command into your terminal: - ```python - pip install "bittensor[torch]" + ```bash + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/opentensor/bittensor/master/scripts/install.sh)" ``` -### Install from PyPi + :::warning For Ubuntu-Linux users + If you are using Ubuntu-Linux, the script will prompt for `sudo` access to install all required apt-get packages. + ::: -You can install Bittensor using any of the below options: + -- **Install SDK**: Run the below command to install Bittensor SDK in the above virtual environment. This will install `btcli` also. -```python -pip install bittensor -``` + -- **Install SDK with `torch`**: Install Bittensor SDK with [`torch`](https://pytorch.org/docs/stable/torch.html). + 1. Clone the Bittensor repo - ```python - pip install bittensor[torch] - ``` - In some environments the above command may fail, in which case run the command with added quotes as shown below: + ```bash + git clone https://github.com/opentensor/bittensor.git + ``` - ```python - pip install "bittensor[torch]" - ``` + 2. Change to the Bittensor directory: + + ```bash + cd bittensor + ``` + + 3. Install the SDK using any one of the following options: + + - **Install SDK**: Run the below command to install Bittensor SDK in the above virtual environment. This will also install `btcli`. + + ```python + pip install . + ``` -- **Install SDK with `cubit`**: Install Bittensor SDK with [`cubit`](https://github.com/opentensor/cubit). + - **Install SDK with `torch`**: Install Bittensor SDK with [`torch`](https://pytorch.org/docs/stable/torch.html). - 1. Install `cubit` first. See the [Install](https://github.com/opentensor/cubit?tab=readme-ov-file#install) section. **Only Python 3.9 and 3.10 versions are supported**. - 2. Then install SDK with `pip install bittensor`. + ```python + pip install bittensor[torch] + ``` + If the command fails in your environment, try enclosing the argument in quotes as shown: + + ```python + pip install "bittensor[torch]" + ``` + + + + ## Install on Windows -To install and run Bittensor SDK on Windows you must install [**WSL 2** (Windows Subsystem for Linux)](https://learn.microsoft.com/en-us/windows/wsl/about) on Windows and select [Ubuntu Linux distribution](https://github.com/ubuntu/WSL/blob/main/docs/guides/install-ubuntu-wsl2.md). +To install and run Bittensor SDK on Windows you must install [**WSL 2** (Windows Subsystem for Linux)](https://learn.microsoft.com/en-us/windows/wsl/about) on Windows and select [Ubuntu Linux distribution](https://github.com/ubuntu/WSL/blob/main/docs/guides/install-ubuntu-wsl2.md). After you installed the above, follow the same installation steps described above in [Install on macOS and Linux](#install-on-macos-and-linux). :::danger Limited support on Windows While wallet transactions like delegating, transfer, registering, staking can be performed on a Windows machine using WSL 2, the mining and validating operations are not recommended and are not supported on Windows machines. - ::: - +::: ## Verify the installation -You can verify your installation in either of the two ways as shown below: - -### Verify using `btsdk` version +You can verify your installation in either of the following ways shown: + + +Run the following command in your terminal: ```python python3 -m bittensor ``` +The response will show you the `` of the `btsdk` you just installed as shown: ```bash Bittensor SDK version: ``` -The above command will show you the `` of the `btsdk` you just installed. - + + -### Verify using Python interpreter - -1. Launch the Python interpreter on your terminal. +1. Launch the Python interpreter on your terminal. ```bash python3 ``` -2. Enter the following two lines in the Python interpreter. - + +2. Enter the following two lines in the Python interpreter: + ```python import bittensor as bt print( bt.__version__ ) ``` + The Python interpreter output will look like below: ```python >>> print( bt.__version__ ) ``` -You will see the version number you installed in place of ``. -### Verify by listing axon information -You can also verify the Bittensor installation by listing the axon information for the neurons. Enter the following lines in the Python interpreter. +You will see the version number you installed in place of ``. + + + +You can also verify the Bittensor installation by listing the axon information for the neurons. + +First, launch the Python interpreter in your terminal: + +```bash +python3 +``` + +Next, enter the following lines in the Python interpreter: ```python import bittensor as bt metagraph = bt.metagraph(1) metagraph.axons[:10] ``` + The Python interpreter output will look like below. ```bash @@ -175,3 +211,9 @@ The Python interpreter output will look like below. >>> ``` + + + +## Developer reference + +For a full developer reference of the Bittensor SDK, see the [Bittensor SDK section](../sdk/bt-api-ref.md). diff --git a/docs/glossary.md b/docs/glossary.md deleted file mode 100644 index 8ba3655f8f..0000000000 --- a/docs/glossary.md +++ /dev/null @@ -1,396 +0,0 @@ ---- -title: "Glossary" ---- - -# Glossary - -## A - -### Active UID - -A UID slot that is considered active within a specific subnet, allowing the associated hotkey to participate as a subnet validator or subnet miner. - -### Archive Node - -A type of public subtensor node that stores the entire blockchain history, allowing for full data access and querying capabilities. - -### Axon - -A module in the Bittensor API that uses the FastAPI library to create and run API servers. Axons receive incoming Synapse objects. Typically, an Axon is the entry point advertised by a subnet miner on the Bittensor blockchain, allowing subnet validators to communicate with the miner. - -## B - -### Bicameral Legislature - -A two-tier legislative system comprising the Triumvirate and the Senate for proposal approval. - -### Bittensor Wallet - -A digital wallet that holds the core ownership in the Bittensor network and serves as the user's identity technology underlying all operations. - -### Block - -A unit of data in the Bittensor blockchain, containing a collection of transactions and a unique identifier (block hash). A single block is processed every 12 seconds in the Bittensor blockchain. - -## C - -### Coldkey - -A component of a Bittensor wallet responsible for securely storing funds and performing high-risk operations such as transfers and staking. It is encrypted on the user's device. This is analogous to a private key. - -### Coldkey-hotkey pair - -A combination of two keys, a coldkey for secure storage and high-risk operations, and a hotkey for less secure operations and network interactions. - -### Commit Reveal - -The commit reveal feature is designed to solve the weight-copying problem by giving would-be weight-copiers access only to stale weights. Copying stale weights should result in validators departing from consensus. - -See [Commit Reveal](./subnets/commit-reveal.md) for details. - -### Consensus - -A measure of a subnet validator's agreement with other validators on the network, calculated based on their trust scores. This is a κ-centered sigmoid of trust, influencing the emission calculation. - -## D - -### Delegate - -A subnet validator that receives staked TAO tokens from delegators and performs validation tasks in one or more subnets. - -### Delegate Stake - -The amount of TAO staked by the delegate themselves. - -### Validator Take % - -The percentage of emissions a validator takes, of the portion that depends on delegated stake (not including their emissions in proportion to their own self-stake), before the remainder is extracted back to the stakers. - -See [Emissions](./emissions). - -### Delegation - -Also known as staking, delegating TAO to a validator (who is thereby the delegate), increases the validator's stake and secure a validator permit. - -### Dendrite - -A client instance used by subnet validators and subnet miners to transmit information to axons on subnet miners and subnet validators. Dendrites communicate with axons using the server-client (Axon-dendrite) protocol. - -### Deregistration - -The process of removing a subnet miner or a subnet validator from the subnet due to poor performance. - -## E - -### EdDSA Cryptographic Keypairs - -A cryptographic algorithm used to generate public and private key pairs for coldkeys and hotkeys in the Bittensor wallet. - -### Effective stake - -The total staked TAO amount of a delegate, including their own TAO tokens and those delegated by nominators. - -### Emission - -Every block, currency is injected into each subnet in Bittensor, and every tempo (or 360 blocks), it is extracted by participants (miners, validators, stakers, and subnet creators). - -Emission is this process of generating and allocating currency to participants. The amount allocated to a given participant over some duration of time is also often referred to as 'their emissions' for the period. - -See [emissions](./emissions). - -### Encrypting the Hotkey - -An optional security measure for the hotkey. - -### External Wallet - -A Bittensor wallet created through the Bittensor website or using a tool like [subkey](https://docs.substrate.io/reference/command-line-tools/subkey/), allowing users to use TAO without installing Bittensor. - -## H - -### Hotkey - -A component of a Bittensor wallet responsible for less secure operations such as signing messages into the network, secure a UID slot in a subnet, running subnet miners and subnet validators in a subnet. It can be encrypted or unencrypted, but is unencrypted by default. The terms "account" and "hotkey" are used synonymously. - -### Hotkey-Coldkey Pair - -Authentication mechanism for delegates and nominators and for delegates participating in the Senate. - -## I - -### Immunity Period - -A grace period granted to a newly registered subnet miner or subnet validator, during which they will not be deregistered due to performance. Allows a miner or validator new to the subnet to adapt and improve their performance, in order to avoid deregistration once the immunity period expires. - -### Incentives - -A portion of the TAO emission received by the subnet miners when they provide valuable services and compete for UID slots in a subnet. - -### Incentive Mechanism - -A system that drives the behavior of subnet miners and governs consensus among subnet validators in a Bittensor subnet. Each subnet has its own incentive mechanism, which should be designed carefully to promote desired behaviors and penalize undesired ones. - -## L - -### Lite Node - -A type of public subtensor node that stores limited blockchain data and relies on archive nodes for full historical data. - -### Local Blockchain - -A private blockchain used for developing and testing subnet incentive mechanisms. A local blockchain is not public and is isolated from any Bittensor network. - -### Local Wallet - -A Bittensor wallet created on the user's machine, requiring the installation of Bittensor. - -### Loss Function - -In the context of machine learning, a mathematical function that measures the difference between the predicted output and the ground truth. In Bittensor, incentive mechanisms act as loss functions that steer subnet miners towards desirable outcomes. - -## M - -### Mainchain - -The primary Bittensor blockchain network, used for production purposes and connected to lite or archive nodes. - -### Metagraph - -A data structure that contains comprehensive information about the current state of a subnet, including detailed information on all the nodes (neurons) such as subnet validator stakes and subnet weights in the subnet. Metagraph aids in calculating emissions. - -### Miner Deregistration - -The process of removing a poor-performing subnet miner from a UID slot, making room for a newly registered miner. - -See [Mining in Bittensor: Miner Deregistration](./miners/#miner-deregistration) - -### Mnemonic - -A sequence of words used to regenerate keys, in case of loss, and restore coldkeys and hotkeys in the Bittensor wallet. - -## N - -### NaCl Format - -A secure encryption format, using the [NaCl](https://nacl.cr.yp.to/) library, used for updating legacy Bittensor wallets to improve security. - -### Netuid - -A unique identifier assigned to a subnet within the Bittensor network. - -### Neuron - -The basic computing node in a Bittensor subnet, representing a node in a neural network. Neurons can be either subnet validators or subnet miners. - -### Nominate - -The process of a delegate registering themselves as a candidate for others to stake their $TAO to. - -### Nominator - -Another term for a delegator. A subnet validator who nominates their own hotkey as a delegate, allowing others to delegate their TAO to the nominator's hotkey. - -### Nominator (Delegator) - -A TAO holder who delegates their stake. - -## O - -### Objective Function - -In the context of machine learning and subnet operations, this refers to the goal that the subnet is continuously optimizing for, through its incentive mechanism. - -## P - -### Private Key - -A private component of the cryptographic key pair, crucial for securing and authorizing transactions and operations within the Bittensor network. - -### Proposal - -A suggestion or plan put forward by the Triumvirate for the Senate to vote on. - -### Proposal hash - -A unique identifier for a proposal used in the voting process. - -### Public Key - -A cryptographic key that is publicly available and used for verifying signatures, encrypting messages, and identifying accounts in the Bittensor network. This is the publicly shareable part of the cryptographic key pair associated with both the coldkey and hotkey, allowing others to securely interact with the wallet. - -### Public Subtensor - -A publicly accessible node in the Bittensor network that can be run as a lite node or an archive node and synchronized with either the mainchain or testchain. - -## R - -### RAO - -A denomination of TAO, representing one billionth (10-9) of a TAO. - -### Rank - -A measure of a subnet miner's performance relative to other subnet miners in the same subnet, calculated based on the subnet miner's trust and incentive scores. This is the sum of weighted stake, contributing to the emission process. - -### Recycling, burning, and locking - -"Recycling TAO" means that this TAO is put back into the Bittensor emissions system. Instead of minting new TAO this recycled TAO that is in the recycle bin will be used again in the new emissions. - -This happens in two cases: - -- When you register either as a subnet validator or a subnet miner and get a `UID` in return, the registration cost TAO you pay is recycled. -- Emissions are recycled for those subnets that have registration turned off or paused. - -When TAO is burned it is permanently removed from circulation, reducing total supply. - -Locked TAO is neither recycled nor burned, but held unspent, without the ability to move it until it is unlocked. The cost for subnet registration is locked and returned if the subnet is deregistered. - -### Regenerating a Key - -The process of recreating a lost or deleted coldkey or hotkey using the associated mnemonic. - -### Register - -The process of registering keys with a subnet and purchasing a UID slot. - - -## S - -### SS58 Encoded - -A compact representation of public keys corresponding to the wallet's coldkey and hotkey, used as wallet addresses for secure TAO transfers. - -### Senate - -A group of elected delegates formed from the top K delegate hotkeys, responsible for approving or disapproving proposals made by the Triumvirate. - -### Stake - -The amount of currency tokens delegated to a validator UID in a subnet. Includes both self-stake (from the validator's own cold-key) and stake delegated from others. - -Stake determines a validator's weight in consensus as well as their emissions. - -### Staking - -The process of attaching TAO to a hotkey, i.e., locking TAO to a hotkey, to participate as a subnet validator, and to secure a validator permit. - -### Subnet - -A Bittensor subnet is an incentive-based competition market that produces a specific kind of digital commodity. It consists of a community of miners that produce the commodity, and a community of validators that measures the miners' work to ensure its quality. - -### Subnet Incentive Mechanism - -The framework that governs the behavior of subnet miners and ensures consensus among subnet validators by promoting desirable actions and penalizing undesired ones. - -### Subnet Miner - -The task-performing entity within a Bittensor subnet. A subnet miner is a type of node in a Bittensor subnet that is connected only to subnet validators. Subnet miners are isolated from the external world and communicate bidirectionally with subnet validators. A subnet miner is responsible for performing tasks given to them by the subnet validators in that subnet. - -### Subnet Creator - -The individual or entity responsible for defining the specific digital task to be performed by subnet miners, implementing an incentive mechanism, and providing sufficient documentation for participation in the subnet. - -### Subnet Protocol - -A unique set of rules defining interactions between subnet validators and miners, including how tasks are queried and responses are provided. - -### Subnet scoring model - -A component of the incentive mechanism that defines how subnet miners' responses are evaluated, aiming to align subnet miner behavior with the subnet's goals and user preferences. It is a mathematical object that converts miner responses into numerical scores, enabling continuous improvement and competition among miners. - -### Subnet Task - -A key component of any incentive mechanism that defines the work the subnet miners will perform. The task should be chosen to maximize subnet miner effectiveness at the intended use case for the subnet. - -### Subnet Validator - -A type of node in a subnet that creates tasks, evaluates the performance of subnet miners and sets weights based on their output. A subnet validator is connected only to subnet miners and to the external world. Subnet validators receive inputs from the external world and communicate bidirectionally with subnet miners. - -### Subnet Weights - -The importance assigned to each subnet determined by relative price among subnets and used to determine the percentage emissions to subnets. - -### Subtensor - -[Subtensor](https://github.com/opentensor/subtensor) is Bittensor's layer 1 blockchain based on substrate (now PolkadotSDK). This serves Bittensor as a system of record for transactions and rankings, operates Yuma Consensus, and emits liquidity to participants to incentivize their participation in network activities. - -The Bittensor SDK offers the [`bittensor.core.subtensor`](pathname:///python-api/html/autoapi/bittensor/core/subtensor/index.html) and [`bittensor.core.async_subtensor`](pathname:///python-api/html/autoapi/bittensor/core/async_subtensor/index.html) modules to handle Subtensor blockchain interactions. - -### Sudo - -A privileged key for administrative actions, replaced by governance protocol for enhanced security. - -### Synapse - -A data object used by subnet validators and subnet miners as the main vehicle to exchange information. Synapse objects are based on the BaseModel of the Pydantic data validation library. - -## T - -### TAO (τ) - -The cryptocurrency of the Bittensor network, used to incentivize participation in network activities (mining, validation, subnet creation and management). A single TAO is newly created (i.e., minted) every 12 seconds on the Bittensor blockchain. - -### Tempo - -A 360-block period during which the Yuma Consensus calculates emissions to subnet participants based on the latest available ranking weight matrix. A single block is processed every 12 seconds, hence a 360-block tempo occurs every 4320 seconds or 72 minutes. - -### Transfer - -The process of sending TAO tokens from one wallet address to another in the Bittensor network. - -### Triumvirate - -A group of three Opentensor Foundation employees responsible for creating proposals. - -### Trust - -A measure of a subnet miner's reputation and reliability, calculated based on the consensus of subnet validators. - -### Trust (T) - -A measure of the confidence in a subnet based on the stakes that set non-zero weights. - -## U - -### UID Slot - -A position occupied by a subnet miner or subnet validator within a subnet, identified by a unique UID. The UID is assigned to a hotkey when it is registered in a subnet, allowing the hotkey to participate as a subnet validator or subnet miner. - -## V - -### VPermit - -Validator permits held by the delegate for specific subnets. - -### Validator Module - -The software component that subnet validators run to perform their subnet validation operations within a subnet. - - -## W - -### Wallet Address - -A unique identifier derived from the public key, used as a destination for sending and receiving TAO tokens in the Bittensor network. - -### Wallet Location - -The directory path where the generated Bittensor wallets are stored locally on the user's machine. - -### Weight Matrix - -A matrix formed from the ranking weight vectors of all subnet validators in a subnet, used as input for the Yuma Consensus module to calculate emissions to that subnet. - -### Weight Vector - -A vector maintained by each subnet validator, with each element representing the weight assigned to a subnet miner based on its performance. - -The ranking weight vectors for each subnet are transmitted to the blockchain, where they combine to form the [weight matrix](#weight-matrix) that is input for Yuma Consensus. - -## Y - -### Yuma Consensus - -The consensus mechanism in the Bittensor blockchain that computes emissions to participants. - -See [Yuma Consensus](./yuma-consensus.md) diff --git a/docs/governance.md b/docs/governance/governance.md similarity index 96% rename from docs/governance.md rename to docs/governance/governance.md index 31104c694f..f9b7e6bbcd 100644 --- a/docs/governance.md +++ b/docs/governance/governance.md @@ -6,7 +6,7 @@ title: "Governance Overview" Bittensor's governance protocol transitions the management of the network from centralization within the foundation to community ownership over time. -The first stage of this transition to decentralized management is the creation of a bicameral legislature. In this stage, the [Triumvirate](./glossary.md#triumvirate) creates proposals for the [Senate](./senate.md) to approve. +The first stage of this transition to decentralized management is the creation of a bicameral legislature. In this stage, the [Triumvirate](../resources/glossary.md#triumvirate) creates proposals for the [Senate](./senate.md) to approve. Triumvirate members are Opentensor Foundation employees, while the Senate is formed from the top K delegate hotkeys. @@ -39,9 +39,11 @@ Consider the following: **Triumvirate** `Bob` has a novel concept for a subnet and wishes to deploy it on the Bittensor network. `Bob` creates a proposal with the calldata: + ```python SubtensorModule.SudoAddNetwork(netuid, tempo, modality) ``` + and sends the transaction to the network in order to broadcast the proposal. **Senate** diff --git a/docs/senate.md b/docs/governance/senate.md similarity index 94% rename from docs/senate.md rename to docs/governance/senate.md index 232be41196..e103388b4e 100644 --- a/docs/senate.md +++ b/docs/governance/senate.md @@ -4,7 +4,7 @@ title: "Senate" # Senate -The Senate is a group of delegates who have elected to participate in proposals, and who control a significant portion of total network stake. +The Senate is a group of delegates who have elected to participate in proposals, and who control a significant portion of total network stake. All members of the network who have delegated stake to any of these Senate members are represented by the party that controls the delegate they've chosen to stake with. This allows any holder within the network to be represented, and to make their opinion known by delegating with organizations who represent their interests. @@ -14,10 +14,10 @@ In order to participate in the Senate, a coldkey must: - Have registered with any subnetwork as a hotkey-coldkey pair. - Have a hotkey stake value is greater than 2% of the network's total stake amount, through delegation or self-stake. -- Have elected to participate in the Senate. +- Have elected to participate in the Senate. -Once all four of the requirements have been fulfilled by a coldkey-hotkey pair, they can vote on any proposal created by the [Triumvirate](glossary#triumvirate). +Once all four of the requirements have been fulfilled by a coldkey-hotkey pair, they can vote on any proposal created by the [Triumvirate](../resources/glossary#triumvirate). In the case that the Senate has all twelve seats filled, and a delegate wishes to join, they will replace the lowest stake member as long as they have more stake in the network. diff --git a/docs/governance/senators-btcli-guide.md b/docs/governance/senators-btcli-guide.md index 00b2a24235..0d897ed9d5 100644 --- a/docs/governance/senators-btcli-guide.md +++ b/docs/governance/senators-btcli-guide.md @@ -6,25 +6,25 @@ title: "Senator's Guide to `BTCLI`" Governance participants (senate members, sudo-level accounts) can propose changes, cast votes, or execute privileged commands that affect the entire network. They must have a **coldkey** with the relevant governance role (senate membership or sudo privileges). -See [Requirements for Senate participation](../senate) +See [Requirements for Senate participation](./senate) -This page discusses btcli considerations specifically for Senators. For general coverage of BTCLI and permissions stuff, see: [Bittensor CLI: Permissions Guide](../btcli-permissions) +This page discusses btcli considerations specifically for Senators. For general coverage of BTCLI and permissions stuff, see: [Bittensor CLI: Permissions Guide](../btcli/btcli-permissions) -See also: [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security). +See also: [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security). - -See: [Senate](../senate). +See: [Senate](./senate). ## **Commands most relevant to governance:** + **Senate / Proposals** (coldkey with senator role): - - `btcli sudo senate` - - `btcli sudo proposals` - - `btcli sudo senate-vote` - - `btcli sudo senate_vote` + +- `btcli sudo senate` +- `btcli sudo proposals` +- `btcli sudo senate-vote` +- `btcli sudo senate_vote` ## Key rotation If you suspect your coldkey may have been leaked, you can request to swap it out of your wallet, using an extrinsic blockchain transaction. This operation has a 5 day waiting period, during which your coldkey will be locked. The cost of this coldkey swap transaction is 0.1 TAO. -See [Rotate/Swap your Coldkey](../subnets/schedule-coldkey-swap) - +See [Rotate/Swap your Coldkey](../keys/schedule-coldkey-swap) diff --git a/docs/index.md b/docs/index.md index acd733296d..ad52ac9dbe 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,6 @@ import { SiFuturelearn } from "react-icons/si"; import { GoNumber } from "react-icons/go"; import { VscFileMedia } from "react-icons/vsc"; - # Bittensor Documentation Bittensor is an open source platform where participants produce best-in-class digital commodities, including compute power, storage space, artificial intelligence (AI) inference and training, protein folding, financial markets prediction, and many more. @@ -52,7 +51,7 @@ Browse the subnets and explore links to their code repositories on [TAO.app](htt ## Participate - You can participate in an existing subnet as either a subnet validator or a subnet miner, or by staking your TAO to running validators. @@ -168,7 +166,7 @@ See [Legacy Bittensor 7.4.0 Documentation](pathname:///legacy-python-api/html/in ( + +

+ Neither the Opentensor Foundation nor Latent Holdings has the technical or legal ability to intervene if your tokens are lost due to theft, scam, or accidental loss of your keys. If you believe you have been the victim of a crime, contact your local law enforcement. +

+
+); diff --git a/docs/keys/address-poisoning-scams.md b/docs/keys/address-poisoning-scams.md new file mode 100644 index 0000000000..acd77e2850 --- /dev/null +++ b/docs/keys/address-poisoning-scams.md @@ -0,0 +1,134 @@ +--- +title: "Address Poisoning Scams: Protect Your Wallet" +--- + +import { SecurityWarning } from "../keys/_security-warning.mdx"; + +# Address Poisoning Scams: Protect Your Wallet + +Address poisoning is one of the most successful cryptocurrency scams, with over $83 million stolen from more than 6,600 victims on Ethereum and Binance Smart Chain alone. Because Bittensor wallets have a similar vulnerability, users of Bittensor wallets should understand how to protect themselves. + + + +## What is Address Poisoning? + +Address poisoning exploits a simple human weakness: long wallet addresses are hard to read. + +Here's how the scam works: + +1. You make a transaction to a legitimate address (like `0x3b75...2712a`) +2. An attacker generates a fake address that looks very similar (like `0x3b75...2712b` or `0x3b74...2712a`) + - They do this by brute-force generating millions of private keys and checking for matches with target addresses + - When they find one that matches the first and last characters of a target's address, they keep it + - This is computationally expensive but profitable - it's called "vanity address generation" +3. Within minutes—often less than 20 minutes—the scammer "poisons" your transaction history by sending you a tiny amount (or even zero) of tokens from their fake address +4. Later, when you're in a hurry, you copy an address from your recent transactions or wallet history +5. You accidentally send funds to the scammer's lookalike address instead of your intended recipient + +The transactions are irreversible. Your funds are gone. + + +## What Makes Bittensor Vulnerable? + +Bittensor uses the Substrate blockchain framework, which, like Ethereum, represents addresses as long hexadecimal strings. This makes Bittensor wallets vulnerable to the same address poisoning tactics as most other blockchains. + +Both Substrate and Ethereum derive addresses from private keys using similar cryptographic processes: +- **Private key** (random) → **Public key** (via elliptic curve) → **Address** (via hashing) + +You can't choose an address directly, but attackers can **brute-force generate millions of key pairs** until they find an address that matches the target pattern. This is computationally expensive but absolutely possible: +- Matching 7 characters: achievable with a laptop CPU +- Matching 14 characters: requires dedicated computing +- Matching 20 characters: requires GPU clusters (some attackers use these!) + +[Research](#research-source) found that one attack group spent an estimated \$1.7 million on computing to generate their lookalike addresses, but made \$4 million in profit. + +Whether you're: +- Transferring TAO +- Managing stake +- Delegating to validators +- Sending funds to a coldkey + +## The Economics: Why This Scam Is So Prevalent + +[Research](#research-source) shows address poisoning is a highly profitable criminal enterprise: + +- Low success rate, high volume: Only 0.01% of poisoning attempts succeed, but scammers compensate by attacking millions of victims +- Organized crime: The largest attack groups have made $26+ million in profit over two years +- Cheap to execute: Each poisoning attempt costs only about \$1 on Ethereum and $0.01 on BSC +- Sophisticated operations: Some groups use GPU computing to generate extremely convincing lookalike addresses with 20 matching characters + +One successful attack of $20,000 pays for 20,000 failed attempts. The math works in favor of the scammers. + +## Who's Most at Risk? + +[Research](#research-source) shows that scammers don't attack randomly. They specifically target users who: + +- Have high balances: Victims targeted had significantly more funds than average users +- Are very active: Users making frequent transactions are attacked more often +- Make large transfers: The bigger your typical transaction, the more likely you are to be targeted +- Use centralized exchanges: Many attackers generate fake addresses mimicking exchange deposit addresses + + +## How to Protect Yourself + +Address poisoning succeeds because of one thing: inattention during routine tasks. + +The best defense is simple but requires discipline: +- Slow down when sending transactions +- Verify addresses completely before clicking send +- Use an address book instead of transaction history +- Trust your caution, not your convenience + +Five extra seconds of verification can save you thousands of dollars. These aren't random attacks. If you're an active user with significant holdings, you're likely being targeted right now. Your transaction history may already be poisoned. + +### 1. Always Double-Check the Full Address + +Before sending any transaction: +- Expand and read the complete address, not just the abbreviated version +- Check the beginning AND the end—scammers match both +- If possible, verify the address through a second channel (message the recipient, check a saved note, etc.) + +### 2. Use an Address Book + +- Maintain a saved list of trusted addresses with clear labels +- Never select addresses from your transaction history—always use your saved address book +- Most wallet applications support address books or contact lists + +### 3. Be Suspicious of Unexpected Transfers + +Scammers exist, so do not give unknown parties "the benefit of the doubt." If you receive unexpected transfers for very small amounts ("dust"), they are likely attempts to seed your transaction history for address poisoning. + +### 4. Send a Test Transaction First + +For large transfers: +- Send a very small amount first +- Verify the recipient received it +- Then send the full amount + +This two-step process can save you from a costly mistake. + +### 5. Use Wallet Apps with Protection Features + +Some wallet applications and blockchain scanners now flag suspicious addresses or hide poisoning attempts. Keep your wallet software updated. + +The [TAO.app](https://www.tao.app) UI includes a warning for addresses flagged as suspicious. + +### 6. Never Rush Important Transactions + +Scammers count on you being in a hurry. If you're tired, distracted, or rushing your procedures, consider taking a break before conducting irreversible blockchain transactions. The blockchain will still be there in an hour. Your funds won't be if you make a mistake. + + +## Learn More + +Your private key is your identity in cryptocurrency. One careless transaction can mean permanent, irreversible loss. Always verify. Always double-check. + +Further reading: + +- [Wallets, Coldkeys and Hotkeys in Bittensor](../keys/wallets.md) +- [Working with Keys](../keys/working-with-keys.md) +- [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security.md) + +### Research Source + +This guide is based on the largest study of this scam to date: Tsuchiya, T., Dong, J.-D., Soska, K., & Christin, N. (2025). "Blockchain Address Poisoning," in *Proceedings of the 34th USENIX Security Symposium*. Seattle, WA, USA. [https://www.usenix.org/conference/usenixsecurity25/presentation/tsuchiya](https://www.usenix.org/conference/usenixsecurity25/presentation/tsuchiya) + diff --git a/docs/getting-started/coldkey-hotkey-security.md b/docs/keys/coldkey-hotkey-security.md similarity index 83% rename from docs/getting-started/coldkey-hotkey-security.md rename to docs/keys/coldkey-hotkey-security.md index 9144697eae..9a492f948a 100644 --- a/docs/getting-started/coldkey-hotkey-security.md +++ b/docs/keys/coldkey-hotkey-security.md @@ -2,6 +2,8 @@ title: "Coldkey and Hotkey Workstation Security" --- +import { SecurityWarning } from "./_security-warning.mdx"; + # Coldkey and Hotkey Workstation Security This page goes into detail of security concerns for working with coldkeys and hotkeys in Bittensor. @@ -9,8 +11,8 @@ This page goes into detail of security concerns for working with coldkeys and ho See also: - [Intro to Wallets, Coldkeys and Hotkeys in Bittensor](./wallets) -- [Bittensor CLI: Permissions Guide](../btcli-permissions) -- [Handle your Seed Phrase/Mnemonic Securely](../keys/handle-seed-phrase) +- [Bittensor CLI: Permissions Guide](../btcli/btcli-permissions) +- [Handle your Seed Phrase/Mnemonic Securely](./handle-seed-phrase) Interacting with Bittensor generally falls into one of three levels of security, depending on whether you need to use your coldkey private key, hotkey private key, or neither. @@ -20,27 +22,30 @@ The workstations you use to do this work can be referred to as a permissionless - [Coldkey workstation](#permissionless-workstation) - [Hotkey workstation](#permissionless-workstation) + + ## Permissionless workstation -You can check public information about Bittensor wallets (including your TAO and alpha stake balances), subnets, validators, and more *without* using a (coldkey or hotkey) private key. This is because transaction information is public on the Bittensor blockchain, with parties being identified by their wallet's coldkey public key. +You can check public information about Bittensor wallets (including your TAO and alpha stake balances), subnets, validators, and more _without_ using a (coldkey or hotkey) private key. This is because transaction information is public on the Bittensor blockchain, with parties being identified by their wallet's coldkey public key. -When you use a website and apps with *only your public key*, this is considered "permissionless" work. Whenever possible, you should do permissionless work on a **permissionless workstation**, meaning a device (laptop or desktop computer, mobile phone, tablet, etc.) that does *not* have your coldkey private key loaded into it. +When you use a website and apps with _only your public key_, this is considered "permissionless" work. Whenever possible, you should do permissionless work on a **permissionless workstation**, meaning a device (laptop or desktop computer, mobile phone, tablet, etc.) that does _not_ have your coldkey private key loaded into it. -In other words, don't use your coldkey private key when you don't have to, and avoiding loading it into devices unnecessarily. Every device that *does* have your coldkey private key loaded into it is a **coldkey workstation**, and should be used with security precautions. +In other words, don't use your coldkey private key when you don't have to, and avoiding loading it into devices unnecessarily. Every device that _does_ have your coldkey private key loaded into it is a **coldkey workstation**, and should be used with security precautions. -When you just want to read/check the state of the blockchain (balances, emissions, token prices, etc.) and you don't need to use your coldkey to *change* anything (for exmaple, to transfer TAO or move stake), it is preferable to use a permissionless workstation. +When you just want to read/check the state of the blockchain (balances, emissions, token prices, etc.) and you don't need to use your coldkey to _change_ anything (for exmaple, to transfer TAO or move stake), it is preferable to use a permissionless workstation. To use the Bittensor CLI `btcli` as a permissionless workstation: -1. Importing your coldkey ***public key*** (not private key) with: - ```shell - btcli w regen-coldkeypub --ss58 - ``` +1. Importing your coldkey **_public key_** (not private key) with: + + ```shell + btcli w regen-coldkeypub --ss58 + ``` -1. View your balances and stakes, as well as information about the Bittensor blockchain, subnets, miners, validators, etc., simply by running: - ```shell - btcli view dashboard - ``` +1. View your balances and stakes, as well as information about the Bittensor blockchain, subnets, miners, validators, etc., simply by running: + ```shell + btcli view dashboard + ``` Websites that offer permissionless browsing of Bittensor data include: @@ -49,22 +54,21 @@ Websites that offer permissionless browsing of Bittensor data include: ## Coldkey workstation -Your coldkey private key, accessible with your recovery [seed phrase](./wallets#the-seed-phrase-aka-mnemonic), is the complete representation of your identity to Bittensor. In otherwords, holding the coldkey or seed phrase is the ultimate authority over your Bittensor wallet. If your coldkey key is leaked or stolen allows an attacker holder to transfer (steal) your TAO, redelegate your stakes, or take other actions that can’t be reversed. Conversely, without your coldkey private key or the seed phrase, there is no possible way to recover access to your wallet. +Your coldkey private key, accessible with your recovery [seed phrase](./wallets#the-seed-phrase-aka-mnemonic), is the complete representation of your identity to Bittensor. In otherwords, holding the coldkey or seed phrase is the ultimate authority over your Bittensor wallet. If your coldkey key is leaked or stolen, it allows an attacker holder to transfer (steal) your TAO, redelegate your stakes, or take other actions that can’t be reversed. Conversely, without your coldkey private key or the seed phrase, there is no possible way to recover access to your wallet. Because of these high stakes, best practices should be diligently followed. Always prioritize confidentiality and integrity over convenience when handling coldkeys. - ### Isolation of coldkey operations The first principle is to isolate coldkey operations from day-to-day or internet-exposed systems. This means using a dedicated machine that is minimally connected to the internet, protected with full disk encryption, and has only highly trusted software installed to minimize the risk of malware or keyloggers intercepting your coldkey. In short, you should approach all operations involving your coldkey management as high-value, mission-critical, and laden with inherent risk. -Ensure a clear boundary between coldkey operations and the working environment you use to carry them out, and everything else. +Ensure a clear boundary between coldkey operations and the working environment you use to carry them out, and everything else. -:::tip Coldkeys do not mine +:::warning Do not mine with coldkeys -Miners will need coldkeys to manage their TAO and alpha currency, as well as hotkeys to serve requests. Ensure there is a clear boundary: The coldkey should **never** be on an environment with untrusted ML code from containers, frameworks, or libraries that might exfiltrate secrets. +Miners will need coldkeys to manage their TAO and alpha currency, as well as hotkeys to serve requests. Miners must ensure that there is a clear boundary—the coldkey should **never** be on an environment with untrusted ML code from containers, frameworks, or libraries that might exfiltrate secrets. ::: ### Coldkey mobile device @@ -82,20 +86,19 @@ This is required for using `btcli` or the Bittensor Python SDK for advanced use ### Operational Hygiene Even on a minimal or air-gapped machine, follow standard security hygiene: -- Always [Handle your Seed Phrase/Mnemonic Securely](../keys/handle-seed-phrase). -- Use strong passwords for your encryption passphrases. -- Do not reuse credentials across different environments. + +- Always [Handle your Seed Phrase/Mnemonic Securely](./handle-seed-phrase). +- Use strong passwords for your encryption passphrases. +- Do not reuse credentials across different environments. - Keep your workstation’s operating system and critical software updated with the latest security patches. - Disable all network services (SSH, RDP, or anything else) that are not strictly needed. - Maintain logs of important oprations. - - ### Rotating your coldkey If you suspect your coldkey may have been leaked, you can request to swap it out of your wallet, using an extrinsic blockchain transaction. This operation has a 5 day waiting period, during which your coldkey will be locked. The cost of this coldkey swap transaction is 0.1 TAO. -See [Rotate/Swap your Coldkey](../subnets/schedule-coldkey-swap) +See [Rotate/Swap your Coldkey](./schedule-coldkey-swap) Effectively, this transfers all of your TAO and alpha stake balances, as well as your `sudo` control over any subnets you have created: @@ -107,7 +110,6 @@ Effectively, this transfers all of your TAO and alpha stake balances, as well as - For each hotkey owned by the old coldkey, ownership transfers to the new coldkey. The list of owned hotkeys for both old and new coldkeys updates. - Any remaining balances transfer from the old coldkey to the new coldkey. - ### Hardware Wallets and Hardware Security Modules (HSMs) Ledger can be integrated with the Bittensor Chrome Extension. This may be a good option for managing stake and TAO balances, but does not allow for advanced functions such as hotkey management, subnet configuration, and governance. @@ -120,7 +122,7 @@ What about Hashicorp Vault? Can you use that with HSM? AWS CloudHSM or Azure Key See: -- [AWS CloudHSM documentation](https://aws.amazon.com/cloudhsm/) +- [AWS CloudHSM documentation](https://aws.amazon.com/cloudhsm/) - Oblique reference to [HashiCorp Vault with HSM integration](https://developer.hashicorp.com/vault/docs/configuration/seal) --> @@ -133,16 +135,10 @@ If you work within a team or DAO environment that collectively manages a coldkey ### Periodic Security Assessments Maintain a secure software environment: -- Keep an eye on newly discovered OS or hardware vulnerabilities. -- Run vulnerability scans on any machine that touches your coldkey. -- Conduct red team exercises and penetration testing to identify weaknesses in your setup. - - - - - - +- Keep an eye on newly discovered OS or hardware vulnerabilities. +- Run vulnerability scans on any machine that touches your coldkey. +- Conduct red team exercises and penetration testing to identify weaknesses in your setup. ## Hotkey workstation @@ -155,8 +151,8 @@ Overall, a hotkey workstation can be considered an “operational” environment Bittensor miners must handle hotkeys in MLOps workflows. Hotkeys must be created in coldkey workstation environments and then provisioned to the mining/hotkey workstation environment, i.e. a server that will handle requests from validators, for example by querying an AI model to generate a response (a generated image or text response) to a text prompt from a user. - Secure secrets management solution (like [HashiCorp Vault](https://www.vaultproject.io/), [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/), or [GCP Secret Manager](https://cloud.google.com/secret-manager)) to provision the hotkey private key or seedphrase to the mining server. -- Use ephemeral secret injection (CI/CD pipelines like GitLab or GitHub Actions allow storing secrets and injecting them at runtime). -- Never put keys in code repositories +- Use ephemeral secret injection (CI/CD pipelines like GitLab or GitHub Actions allow storing secrets and injecting them at runtime). +- Never put keys in code repositories ### Hotkey rotation @@ -164,10 +160,10 @@ If you suspect that a hotkey (but not a coldkey) has been leaked, rotate it as s Note that this operation incurs a $1 \tau$ recycling fee. - ### Minimize dependency risk Bittensor nodes often run complex software stacks with many dependencies. Take steps to reduce risk: -- Keep your Python environment or Docker images updated with the latest patches. -- Avoid installing unnecessary packages that might contain vulnerabilities. -- Consider sandboxing the ML library if possible, using solutions like [PyPy sandboxing](https://doc.pypy.org/en/latest/sandbox.html) or custom Docker seccomp profiles. + +- Keep your Python environment or Docker images updated with the latest patches. +- Avoid installing unnecessary packages that might contain vulnerabilities. +- Consider sandboxing the ML library if possible, using solutions like [PyPy sandboxing](https://doc.pypy.org/en/latest/sandbox.html) or custom Docker seccomp profiles. diff --git a/docs/keys/handle-seed-phrase.md b/docs/keys/handle-seed-phrase.md index c1b2bb19b5..3d22cf1327 100644 --- a/docs/keys/handle-seed-phrase.md +++ b/docs/keys/handle-seed-phrase.md @@ -2,6 +2,8 @@ title: "Handle your Seed Phrase/Mnemonic Securely" --- +import { SecurityWarning } from "./_security-warning.mdx"; + # Handle your Seed Phrase/Mnemonic Securely The seed phrase (a.k.a. 'menemonic' or 'recovery phrase') is a series of (at least 12) words that is generated together with your wallet's cryptographic key pair, and which can be used to recover the coldkey private key. This seed phrase is therefore a human-usable way to save access to the cryptographic wallet offline, and to import the cryptographic wallet into a wallet application. @@ -10,25 +12,27 @@ Whoever holds the seed phrase has full control over the wallet, so you should tr There are two categories of security failure with a secret like a seed phrase/mnemonic: -- To *lose* the secret means no longer having access to it. This implies permanent, unrecoverable loss of the resources (TAO and alpha stake, subnet creator permissions on a subnet, etc.) controlled by a Bittensor coldkey private key. -- To *leak* the secret means accidentally giving someone else access to it. This may result in them stealing your resources, or further leaking it to others who may in turn act maliciously. If your secret is leaked, you can (and should) rotate it, i.e. perform a coldkey swap. +- To _lose_ the secret means no longer having access to it. This implies permanent, unrecoverable loss of the resources (TAO and alpha stake, subnet creator permissions on a subnet, etc.) controlled by a Bittensor coldkey private key. +- To _leak_ the secret means accidentally giving someone else access to it. This may result in them stealing your resources, or further leaking it to others who may in turn act maliciously. If your secret is leaked, you can (and should) rotate it, i.e. perform a coldkey swap. + + See: [Rotating your coldkey](./coldkey-hotkey-security#rotating-your-coldkey) - See: [Rotating your coldkey](../getting-started/coldkey-hotkey-security#rotating-your-coldkey) + ## Do not leak your keys/seed phrase 1. Do not keep paper/analog copies somewhere they can be accessed without your knowledge. -1. Do not expose your seed phrase to untrustworthy software by entering into applications: - - messaging - - email - - online word processors -1. Beware key-logging software if you enter your seed phrase. Never enter your seed phrase on a device that may be compromised with malware! -1. Beware screen capture software if you generate and export your seed phrase. Never enter your seed phrase on a device that may be compromised with malware! +1. Do not expose your seed phrase to untrustworthy software by entering into the following applications: + - messaging + - email + - online word processors +1. Beware of key-logging software when entering your seed phrase. Never enter your seed phrase on a device that may be compromised with malware! +1. Beware of screen capture software if you generate and export your seed phrase. Never enter your seed phrase on a device that may be compromised with malware! 1. Beware cameras and eye-balls (the "over the shoulder" attack) if you generate and export your seed phrase. Don’t write it down or display it on screen in public or semi-public places. ## Do not lose your keys/seed phrase -You must keep redundant backups of your coldkey. If you lose all access to your seed phrase/initialized wallets, you permanently and unrecoverably lose access to your account (TAO, stake, etc.). +You must keep redundant backups of your coldkey. If you lose all access to your seed phrase/initialized wallets, you permanently and unrecoverably lose access to your account (TAO, stake, etc.). ## Backup tactics @@ -54,6 +58,7 @@ Pros: - Can be hard to lose if properly secured in a safe. Cons: + - Easy to leak if physical security is compromised (anyone can read or take a picture of it when the paper is exposed). - Easy to lose to physical disaster (e.g. fire). @@ -68,6 +73,7 @@ Cons: Easy to leak if physical security is compromised (anyone can read or take ### Encrypted drive Tactics: + - Save the seed phrase in an encrypted text file on a USB drive. - Use strong, unique passphrases and encrypt using industry-standard tools (e.g., GPG, VeraCrypt). - Store the USB in a secure physical location—never leave it connected to a device. @@ -84,7 +90,7 @@ Pros: Cons: -- Signing device, *not* full backup; cannot export seed phrase +- Signing device, _not_ full backup; cannot export seed phrase - If lost and not backed up elsewhere, access is lost - High risk of loss due to mistaken factory reset (e.g. wrong PIN too many times) @@ -106,7 +112,7 @@ Pros: Cons: -- Signing device, *not* full backup; cannot export seed phrase +- Signing device, _not_ full backup; cannot export seed phrase - Physical access can compromise keys. - Requires careful configuration for offline mode. - App updates require full device reset and recovery from seed. @@ -124,16 +130,17 @@ For example, you might split a seed phrase into 5 shares, requiring any 3 to res Pros: - Extremely resistant to both single-point loss and leakage: - - The leak of any share does not compromise your wallet. - - The loss of any share does not result in loss of the wallet. + - The leak of any share does not compromise your wallet. + - The loss of any share does not result in loss of the wallet. - Shares can be safely distributed across multiple locations or people. Cons: + - Imposes additional operational complexity. - Stored secret is no longer human readable. Can be remedied with [slip39](https://github.com/satoshilabs/slips/blob/master/slip-0039.md). Tools: + - [`sssa-golang`](https://github.com/SSSaaS/sssa-golang): An implementation of Shamir's Secret Sharing Algorithm in Go. - [Banana Split](https://github.com/paritytech/banana_split): Open source tool that uses a variation of SSS to split a seed phrase into QR codes. - [PyCryptodome SSS](https://pycryptodome.readthedocs.io/en/latest/src/protocol/ss.html): A Python-based implementation of the Shamir scheme. - diff --git a/docs/keys/multisig.md b/docs/keys/multisig.md index da1bc86bcd..c07117c6e6 100644 --- a/docs/keys/multisig.md +++ b/docs/keys/multisig.md @@ -1,8 +1,8 @@ --- -title: "Secure your Coldkey with a Multisig" +title: "Secure your Coldkey with a Multisig Wallet" --- -# Secure a Coldkey with a Multisig +# Secure a Coldkey with a Multisig Wallet A multisig (multiple signatories) wallet is a way of distributing responsibility for a coldkey across a set of wallets, referred to as signatories. Any signatory can propose a transaction, but the action must be agreed by some threshold of others before it will execute. Conventionally, a multisig is described as "$M$ out of $N$", where $M$ is the threshold number of signatories required to sign a transaction and $N$ is the total number of signatories. The signatories on a multisig may be seperate people, or a set of keys controlled by a single individual. This gives multisigs great versatility in providing security against single points of failure, including the loss of a single key or the decision of a team-mate to act irresponsibly. @@ -14,7 +14,7 @@ This page will guide the user through an example practice workflow of creating a - [Install the latest version of BTCLI](../getting-started/install-btcli) - Acquire some Testnet TAO. -- Polkadot-JS: This tutorial will employ the Polkadot-JS browser app, which allows users to submit transactions to Polkadot-based chains, including Bittensor. To use your coldkey private keys with the Polkadot-JS app, you must install the wallet browser extension, which is available for Firefox or Chrome. +- Polkadot-JS: This tutorial will employ the Polkadot-JS browser app, which allows users to submit transactions to Polkadot-based chains, including Bittensor. To use your coldkey private keys with the Polkadot-JS app, you must install the wallet browser extension, which is available for [Firefox](https://addons.mozilla.org/en-US/firefox/addon/polkadot-js-extension/) or [Chrome](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd). ## Provision and configure your workstation @@ -28,17 +28,20 @@ Coldkeys private keys and seed phrases for wallets with real (mainnet) TAO are * In a realistic scenario, using wallets with real (mainnet) TAO, it would be crucial to follow proper workstation security. This implies that each coldkey would be provisioned to its own secure coldkey workstation, as maintaining separate workstations for each coldkey is important for minimizing the risk that multiple of the keys are lost or leaked; storing or handling the keys together undermines the purpose of having multiple keys. -See [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security). +See [Coldkey and Hotkey Workstation Security](./coldkey-hotkey-security). -In the current *practice* scenario, using testnet TAO, we will forego full workstation security for ease, and handle all three keys on a single workstation, which can be an ordinary laptop rather than a secure workstation. +In the current _practice_ scenario, using testnet TAO, we will forego full workstation security for ease, and handle all three keys on a single workstation, which can be an ordinary laptop rather than a secure workstation. ### Configure the target network in the Polkadot-JS web app. 1. Visit the [Polkadot-JS explorer web app](https://polkadot.js.org/apps). -1. Click the blockchain selector tab in the upper lefthand corner of the web page, next to **Accounts**. This is set to **Polkadot** main chain by default. -1. Scroll down and open **Development** at the bottom of the Chains menu, and paste the address for the Bittensor test chain into **custom endpoint**: `wss://test.finney.opentensor.ai:443`. +1. Click the blockchain selector dropdown in the upper lefthand corner of the web page, next to **Accounts**. This is set to **Polkadot** main chain by default. +1. Scroll down and open **Development** at the bottom of the Chains menu, and paste the address for the Bittensor test chain into **custom endpoint** field: `wss://test.finney.opentensor.ai:443`. +1. After pasting the link to the Bittensor test chain, click on the **Switch** button at the top of the menu. - You should see the page update and display live information about Bittensor testnet. + :::tip success + You should see the page update and display live information about Bittensor testnet. + ::: ### Create and import 3 coldkey pairs ("accounts") in the Polkadot-JS browser extension @@ -46,52 +49,81 @@ Each of our 3 signatories needs a wallet. Either create them or re-use available 1. Use `btcli` to create three coldkeys/wallets, or use practice wallets you already have access to. Alternatively, you can create wallets in the Polkadot-JS browser extension. - See [Creating/Importing a Bittensor Wallet](../working-with-keys). + See [Creating/Importing a Bittensor Wallet](./working-with-keys). -1. Load each key into the Polkadot-JS wallet browser extension: - 1. Click to open the browser extension. - 1. Click **+**, then select **Import account from pre-existing seed**. - 1. Provide your seed phrase to regenerate your wallet's coldkey private key. +1. Load each wallet key into the Polkadot-JS wallet browser extension: -1. Configure your keys to use the custom network (Bittensor's test net). For each key/**account**: - 1. Click the menu (three dots) to configure the account. - 1. Open the network dropdown selector, and choose **Allow use on any chain**. + 1. Click the `polkadot{.js}` extension icon in your browser to open the extension. + 1. Click the **+** icon, then select **Import account from pre-existing seed**. + 1. Provide your Bittensor wallet's seed phrase to regenerate your wallet's coldkey private key. + 1. Open the **NETWORK** dropdown selector, and choose **Allow use on any chain**. + 1. Click **Next**. After clicking **Next**, you will be prompted to provide a name and password for the account created. -1. You may need to allow the PolkadotJS webapp to use specific wallets by clicking **connect** in the extension. +1. You will need to allow the PolkadotJS webapp to use specific wallets connecting the imported accounts. To do this: -1. You may need to refresh the PolkadotJS webapp to show updated accounts information. + 1. Click the `polkadot{.js}` extension icon in your browser toolbar to open the extension. -1. Confirm success by visiting the [accounts page](https://polkadot.js.org/apps/#/accounts). You should see all three wallets/accounts listed as **accounts available via browser extensions**. + :::info + Make sure you perform this action while on the same browser tab where the Polkadot-JS Explorer is open. + ::: + + 2. Click the **Connect Accounts** button at the top of the extension. + 3. Select the accounts that you want to connect to the Polkadot-JS browser app—for this walkthrough, select the three signatory accounts created. + 4. Confirm success by visiting the [Accounts page](https://polkadot.js.org/apps/#/accounts). You should see all three wallets/accounts listed as **accounts available via browser extensions**. + + :::info + You may need to refresh the PolkadotJS webapp to show updated accounts information. + ::: ## Create the multisig In this step, we'll create the multisig wallet, specifying the signatory wallets. -1. Navigate to the [accounts page](https://polkadot.js.org/apps/#/accounts). +1. Navigate to the [accounts page](https://polkadot.js.org/apps/#/accounts). + +1. Click **+ Multisig** to create a new multisig. In the **add multisig** modal: + + 1. Select from the available signatories, which must be in your address book (if they are not, add them from the Accounts/Address book tab). + 1. Set the **threshold**. + 1. Set a name for the multisig address on the Polkadot-JS web app. + 1. Click **+ Create**. + + :::info + You should see the newly created multisig account listed under the **multisig** section on the Accounts page. Select the new account to view its name, balance, and SS58 address. + ::: -1. Click **+ Multisig**. In the **add multisig** modal: - 1. Select from the available signatories, which must be in your address book (if they are not, add them from the Accounts/Address book tab). - 1. Set the **threshold**. - 1. Set a name. - 1. Click **create**. +1. Use the `btcli w regen_coldkeypub` command to add the wallet's public key to BTCLI. To do this, run the following command in your terminal: -1. Use `btcli w regen_coldkeypub --wallet.name multisig` to add the wallet's public key to BTCLI. -1. View its balance information with `btcli view dashboard --wallet.name multisig`. + ```sh + btcli w regen_coldkeypub --wallet-name WALLET_NAME --ss58 MULTISIG_ADDRESS + ``` + + Replace `WALLET_NAME` and `MULTISIG_ADDRESS` with the name and ss58 address of the multisig address created in the Polkadot-JS browser app. + +:::info +This command regenerates the public part of a coldkey for the multisig wallet named. You can view its balance information as shown: + +```sh +btcli view dashboard --wallet.name WALLET_NAME +``` + +::: ## Transfer TAO to the multisig wallet. -1. Find the multisig wallet's coldkey public key on the [accounts page](https://polkadot.js.org/apps/#/accounts), listed under **multisig**. Click on the wallet/account to open it's show modal, then click **Copy** by the account name and address/public key to copy it out. -1. Use BTCLI to transfer testnet TAO to the mutlisig wallet. - 1. Run `btcli wallet transfer`. - 1. Provide the multisig wallet's coldkey public key. - 1. Specify the amount. It's recommended to do a small transfer first to confirm the address, even with testnet TAO. +1. Find the multisig wallet's coldkey public key on the [accounts page](https://polkadot.js.org/apps/#/accounts), listed under **multisig**. Click on the wallet/account to open it's show modal, then click **Copy** by the account name and address/public key to copy it out. + +1. Use BTCLI to transfer testnet TAO to the multisig wallet. + 1. Run `btcli wallet transfer`. + 1. Provide the multisig wallet's coldkey public key. + 1. Specify the amount. It's recommended to do a small transfer first to confirm the address, even with testnet TAO. 1. To confirm the transfer, view the multisig wallet in the accounts page or the BTCLI dashboard. It should show the TAO from the transfer almost immediately. -## Transfer TAO from the multisig +## Transfer TAO from the multisig Let's try executing a sensitive operation with the multisig wallet: transferring TAO. Choose any destination wallet that you control. It can be one of the signatories. Note this wallet's balance, so you can confirm the transaction's ultimate success by seeing the increase in that balance. -To transfer TAO out of the multisig wallet requires a multisig transaction, meaning it must be approved by threshold $M$ of the $N$ total signatories. First, one wallet must propose the transaction. This proposal will exist on the blockchain where it can be signed by other signatories, which will execute the proposed transaction. +Transferring TAO out of the multisig wallet requires a multisig transaction, meaning it must be approved by threshold $M$ of the $N$ total signatories. First, one wallet must propose the transaction. This proposal will exist on the blockchain where it can be signed by other signatories, which will execute the proposed transaction. Note that the signatory that proposes a multisig action must make a deposit that will be returned upon approval or rejection of the transaction, the amount of which will be displayed in the multisig transaction modal. The wallet that will propose the multisig transaction must have a balance above this amount. @@ -100,33 +132,36 @@ Note that the signatory that proposes a multisig action must make a deposit that 1. In the Polkadot-JS web app, click the **Developer** tab and select Extrinsics, or navigate to the extrinsics page at [polkadot.js.org/apps/#/extrinsics](https://polkadot.js.org/apps/#/extrinsics). 1. Under **using the selected account**, select the multisig wallet. Note that the multisig wallet's TAO balance is displayed. 1. Under **submit the following extrinsic**: - 1. Select the `balances` module (from the lefthand dropdown menu). - 1. Select `transferKeepAlive`. + 1. Select the `balances` module (from the lefthand dropdown menu). + 1. Then, select `transferKeepAlive` from the righthand menu. 1. Under **Id: AccountId**, paste in the coldkey public key for the destination wallet. -1. Under **value**, put the amount of TAO to transfer. This amount must be available in the multisig wallet. -A wallet with a test TAO balance sufficient to pay the fee +1. Under **value**, put the amount of TAO to transfer. This amount must be available in the multisig wallet. A wallet with a test TAO balance sufficient to pay the fee. + :::info + The `value` field accepts amounts in RAO, the smallest unit of TAO (`1 rao = 10⁻⁹ TAO`). + For example, to transfer `2 TAO`, you must set `value` to `2,000,000,000`. + ::: 1. Copy out the **encoded call data**, which other signatories will need to sign the transaction. 1. Copy out the **encoded call hash**, which other signatories will need to confirm the details of the transaction. 1. Copy out the **link** under **encoding details**, which will allow other signatories to view the details of the transaction and confirm it against the encoded call hash. 1. Click **Submit Transaction**. 1. In the **authorize transaction** modal, select the signatory. - Note that this should be selected as a **multisig signatory**, not as a **proxy account**. You may need to toggle the **Use a proxy for this call** switch to **Don't use a proxy for this call**. + Note that this should be selected as a **multisig signatory**, not as a **proxy account**. You may need to toggle the **Use a proxy for this call** switch to **Don't use a proxy for this call**. -1. Select **Multisig approval with hash (non-final approval)**, not **Multisig message with call (for final approval)**. +1. Click the toggle to select **Multisig approval with hash (non-final approval)** instead of **Multisig message with call (for final approval)**. 1. Click **Sign and Submit**. ### Approve the transaction 1. Return to the [accounts page](https://polkadot.js.org/apps/#/accounts). -1. Find the multisig wallet, noting that it should now display a clickable element for **view pending approvals**. You can also click on the wallets three dot menu and select **Multisig approvals**. +1. Find the multisig wallet; the wallet should now display a clickable element to **View pending approvals**. You can also click on the wallet's menu icon and select **Multisig approvals**. 1. The approval modal will display the **encoded call hash**, allowing signatories to confirm the identity of the proposed transaction, but it does not display details about the call. - To view details of the call, visit the link provided under **encoding details** when creating the transaction proposal. + To view details of the call, visit the link provided under **encoding details** when creating the transaction proposal. - :::caution - Confirm that the **call hash** in the details link matches the **call hash** in the transaction you are approving. This is the only way to be certain you are approving the correct transaction. - ::: + :::caution + Confirm that the **call hash** in the details link matches the **call hash** in the transaction you are approving. This is the only way to be certain you are approving the correct transaction. + ::: 1. Select the approving signatory, which cannot be the signatory who proposed the transaction. 1. If you are the final approver, enter the **encoded call data**, which was provided when the transaction was created, and is displayed at the top of the page at the **encoding details** link. @@ -136,4 +171,4 @@ A wallet with a test TAO balance sufficient to pay the fee ### Confirm success -Check the multisig wallet's balance, which should have decreased by the transfer amount, and the destination wallet, which should have increased. \ No newline at end of file +Check the multisig wallet's balance, which should have decreased by the transfer amount, and the destination wallet, which should have increased. diff --git a/docs/keys/proxies/create-proxy.md b/docs/keys/proxies/create-proxy.md new file mode 100644 index 0000000000..ecfc0714df --- /dev/null +++ b/docs/keys/proxies/create-proxy.md @@ -0,0 +1,186 @@ +--- +toc_max_heading_level: 2 +--- + +# Create a Proxy Account + +This tutorial walks you through creating a standard proxy and executing a call from the proxy account using the Polkadot.js web app. You will set up a delegate account, add it as a proxy to your real account with a chosen `ProxyType`, and optionally use announcements for delayed execution. + +--- + +A standard proxy links a _delegator_ to a known account. The delegator specifies: + +- The _delegate_ account. +- The allowed `ProxyType` (scope of permissions). +- An optional delay. + +The delegate has access to funds in the real account and can then execute calls on behalf of the real account within the constraints of the specified `ProxyType`. + +:::info When to use standard proxies +Delegating through a standard proxy is a good option when you want to entrust control to trusted individuals or organizations who can act on your behalf. In this setup, the delegate maintains their own independent signing capability, which allows them to initiate and authorize actions without relying on your key. This approach provides maximum operational flexibility while also making the delegate responsible for managing the security of their own keys. +::: + +## Prerequisites + +- A locally running subtensor development chain. For more information, see [run a local Bittensor blockchain instance](../../local-build/deploy.md). +- [Polkadot‑JS browser app](https://polkadot.js.org/apps/?#/explorer) and [Polkadot‑JS browser extension](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd) installed. +- An accessible 'Alice' wallet. For more information, see [Provision Wallets for Local Deploy](../../local-build/provision-wallets). +- At least 3 different accounts in your Polkadot-JS app: + - Real (delegator) account that controls funds and adds the proxy. + - Delegate account to perform allowed actions. + - A recipient account to receive transferred funds. + +To import accounts into the Polkadot-JS web app, see [create and import accounts to the Polkadot-JS extension](../../keys/multisig.md#create-and-import-3-coldkey-pairs-accounts-in-the-polkadot-js-browser-extension). + +## Step 1: Connect Polkadot‑JS to your local chain + +1. Open the Polkadot‑JS app. +2. In the network selector, choose Development → custom endpoint `ws://127.0.0.1:9944`. +3. Confirm your local chain metadata loads and your test accounts appear in the **Accounts** tab. + +:::tip +If the web app does not connect to your local chain, your browser’s privacy or security settings may be blocking it. Try adjusting those settings and reconnecting. +::: + +## Step 2: Add a Proxy + +1. In the navbar menu, navigate to **Developers** → **Extrinsics**. +2. Under “using the selected account”, pick the funded delegator account. +3. Under “submit the following extrinsic”, choose the `proxy` pallet and call `addProxy(delegate, proxyType, delay)`. +4. Fill the parameters: + + - `delegate`: select the imported delegate account from the _Accounts_ dropdown. + - `proxyType`: select `SmallTransfer`; this should allow us to transfer amounts that do not exceed 0.5τ. + - `delay`: optionally, include a delay in blocks. + +5. Click **Submit Transaction** and sign with the _delegator_ account. + +Your delegate is now authorized to execute small transfers on behalf of the real account. + +:::info +A delegator can assign multiple proxies to the same delegate account. However, each proxy entry must use a unique `ProxyType`. Attempting to register a duplicate entry with the same delegate and `ProxyType` will result in a `proxy.Duplicate` error. +::: + +### Checking an Account’s Proxies + +You can check which proxies are associated with an account to see their delegate addresses, proxy types, and any configured delays. To do this: + +1. From the **Developer** dropdown, navigate to **Chain state** → **Storage**. +2. Click the **selected state query** menu and select `proxy.proxies`. +3. Select the account used to create the proxy. +4. Click the **+** icon to run the query. + +This returns the set of proxies related to the account and their information—`delegate`, `proxyType`, and `delay`. + +## Step 3: Execute a Proxy Call + +1. Go to **Developer** → **Extrinsics**. +2. Under “using the selected account”, choose the delegate account. +3. Select the `proxy` pallet and choose `proxy(real, forceProxyType, call)`. +4. Fill the parameters: + - `real`: select the real account used to create the proxy. + - `forceProxyType`: leave option unchecked. + - `call`: the call to be made by the delegate account. Fill the following parameters: + - Select the `balances` pallet and choose the `transferKeepAlive(dest, value)` extrinsic. + - `dest`: select the recipient account. + - `value`: input the amount to be transferred in RAO—1 TAO = 19RAO. +5. Click **Submit Transaction** and sign the transaction from the delegate account. + +The runtime verifies that the call is permitted by the proxy filter and that any delay requirements have been met, then dispatches the call as if signed by the Real account. + +:::info +After submitting the transaction, check the Polkadot.JS web app's **Explorer** page for a `balances.Transfer` event. Notice the sender is the delegator account. +::: + +:::warning + +- With the SmallTransfer proxy type, transfers are limited to less than 0.5 TAO (500,000,000 RAO). Use the Transfer proxy type for amounts above this limit. See [source code: SmallTransfer limit definition](https://github.com/opentensor/subtensor/blob/main/common/src/lib.rs#L43). +- The delegate account must hold enough funds to cover transaction fees, which are approximately 25 µTAO (0.000025 TAO). + ::: + +If you configured a non-zero delay when creating the proxy, you must first make an announcement before executing the proxy call. Attempting to execute a proxy call before announcing returns a `proxy.Unannounced` error. + +
+Announce and execute a delayed proxy + +Announcing a delayed proxy call requires the hash of the call that you intend to execute. Therefore, you must first generate the call hash of the transaction you want to carry out. To generate the call hash: + +1. Go to **Developer** → **Extrinsics**. +2. Under “**using the selected account**”, pick the delegate account. +3. Under “**submit the following extrinsic**”, choose the `balances` pallet and call the `transferKeepAlive(dest, value)` extrinsic. +4. Fill the parameters: + - `dest`: select the recipient account. + - `value`: input the amount to be transferred in RAO—1 TAO = 19RAO. +5. Copy the hex code shown in the **encoded call data** field. You will use this to announce the call in the next step. + +--- + +:::info +Do not submit the transaction after entering the parameters. Only copy the encoded call data once all parameters are provided. +::: + +--- + +### Announce a call + +To announce a delayed call: + +1. Go to **Developer** → **Extrinsics** tab. +2. Choose the `proxy` pallet and select the `announce(real, call_hash)` extrinsic. +3. Fill the parameters: + - `real`: select the real account used to create the proxy. + - `callHash`: paste the call hash of the transaction to be executed. +4. Click **Submit Transaction** and sign the transaction from the delegate account. + +Next, wait for the duration of the configured delay—in blocks—before executing the call. During the waiting period, the delegate can cancel the announcement—`removeAnnouncement(real, callHash)`, while the real account retains final authority to reject it—`rejectAnnouncement(delegate, callHash)`. + +### Execute a delayed proxy call + +After the announcement waiting period has passed, the delegate account can now execute the proxy if the real account did not reject it. Attempting to execute the proxy before the waiting period passes returns a `proxy.Unannounced` error. To execute a delayed proxy call: + +1. Go to **Developer** → **Extrinsics**. +2. Under “using the selected account”, choose the delegate account. +3. Select the `proxy` pallet and choose `proxyAnnounced(delegate, real, forceProxyType, call)`. +4. Fill the parameters: + - `delegate`: select the delegate account. + - `real`: select the real account used to create the proxy. + - `forceProxyType`: leave option unchecked. + - `call`: the call to be made by the delegate account. Fill the following parameters: + - Select the `balances` pallet and choose the `transferKeepAlive(dest, value)` extrinsic. + - `dest`: select the recipient account. + - `value`: input the amount to be transferred in RAO—1 TAO = 19RAO. +5. Click **Submit Transaction** and sign the transaction from the delegate account. + +--- + +:::info + +- The call details must exactly match the original announcement. Any change—such as modifying the recipient or amount—will result in a `proxy.Unannounced` error. +- Once a delayed proxy call is executed, its announcement is cleared. To execute another proxy with the same details, you must create a new announcement and wait for the waiting period to pass. + ::: + +--- + +
+ +## Step 4: Remove a Proxy + +1. In the navbar menu, navigate to **Developers** → **Extrinsics**. +2. Under “using the selected account”, pick the delegator account. +3. Under "submit the following extrinsic", choose the `proxy` pallet and call `removeProxy(delegate, proxyType, delay)`. +4. Fill the parameters: + + - `delegate`: select the imported delegate account from the _Accounts_ dropdown. + - `proxyType`: select `SmallTransfer`; this should allow us to transfer amounts that do not exceed 0.5τ. + - `delay`: Optionally, include a delay in blocks. + +5. Click **Submit Transaction** and sign with the _delegator_ account. + +## Troubleshooting + +- `proxy.Duplicate`: A proxy with the same configuration already exists on the real account. See [source code: `Duplicate` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L739). +- `proxy.Unannounced`: A non-zero delay proxy requires an announcement; announce and wait the delay. See [source code: `Unannounced` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L743). +- `proxy.Unproxyable`/`system.CallFiltered`: The call is not permitted under the current `ProxyType`. See [source code: `Unproxyable` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L737). +- `proxy.TooMany`: You exceeded `MaxProxies` or `MaxPending`. Remove unused proxies/announcements. See [source code: `TooMany` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L731). +- `proxy.NotProxy`: Ensure you're submitting from the delegate account and referencing the correct real account. See [source code: `NotProxy` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L735). +- `Token.FundsUnavailable`: Ensure that your real account has enough available funds to cover the transaction. diff --git a/docs/keys/proxies/index.md b/docs/keys/proxies/index.md new file mode 100644 index 0000000000..c2c910586a --- /dev/null +++ b/docs/keys/proxies/index.md @@ -0,0 +1,107 @@ +# Proxies + +This page introduces the proxy pattern used in Bittensor and explains how it enables secure delegation of account permissions for specific classes of calls. + +--- + +## What is a proxy? + +Rather than using funds in a single account, accounts with unique roles can complete tasks on behalf of the main stash account. +A proxy lets one account (the delegator, or "real" account) authorize another account (the delegate) to make permitted calls on its behalf. Proxies allow a delegator to keep their "real" accounts safe and "cold", thereby adding an extra layer of security to the tokens in the account. + +The permission scope is determined by the `ProxyType` call filter. This call filter allows the delegator account to set the roles and limitations of the delegate account. Optionally, actions can require an on-chain announcement period—`delay`, giving the delegator time to reject a call made by a delegate. + +## Proxy terminology + +The following concepts define how proxy relationships are set up and managed: + +- **Real account**: The account whose identity and funds are at stake. +- **Delegate account**: The account with access to tokens in the real account and allowed to perform certain actions for the real account. +- **ProxyType**: A call filter that restricts which calls can be made by the delegate account. +- **Delay/announcement**: Optional time window before a proxy action can be executed. + +## Common use cases + +Proxies enable secure delegation of account responsibilities. Below are common scenarios where proxies are used effectively: + +- **Operational delegation**: run operational tasks (e.g., staking, subnet operations) from a hot wallet while securing funds in a cold wallet. +- **Least-privilege permissions**: only allow a constrained set of calls (e.g., small transfers, staking-only, governance-only). +- **Automated agents**: let bots/services act with limited authority. + +## How it works + +A proxy relationship starts when the _real account_—delegator—creates a proxy entry, which specifies or creates the _delegate account_, the allowed `ProxyType`, and an optional delay. Once this entry exists, the delegate can execute permitted calls on behalf of the real account using the `proxy(real, forceProxyType, call)` extrinsic. + +If the proxy entry includes a non-zero delay, the delegate cannot execute the call immediately. Instead, they must first announce the intended action and wait for the delay period to pass. During this waiting window, the delegator has the ability to reject the announcement, effectively blocking the call. The delegate can also remove a call they previously announced and return the deposit. + +The real account always retains full control over the relationship. It can revoke a delegate’s access at any time by removing the proxy entry, immediately disabling the delegate’s ability to act on its behalf. + +## Types of proxies + +When setting up a proxy, there are two aspects of proxy setup: + +1. **Proxy Account Type** + +This determines how the proxy is set up and managed. When creating a proxy, you can choose between two account types: + +- **Standard Proxy Account**: Registers an existing account as a proxy for the delegator. The assigned account now acts as a delegate and can make calls on behalf of the delegator, according to the configured `ProxyType`. You can create it with the `addProxy` extrinsic. + +- **Pure Proxy Account**: Creates a new account that cannot be accessed directly to act as the delegate. This account is initialized with a proxy of the specified `ProxyType` for the origin sender, and all actions are signed by the delegator on its behalf. You can create it with the `createPure` extrinsic. + +:::warning +Pure proxies are _keyless_, _non-deterministic_ accounts. They have no private key, cannot sign transactions themselves, and cannot be recovered. If the relationship between the delegator and the pure proxy is broken, any funds in the pure proxy account are permanently lost. +::: + +2. **`ProxyType`** + +This defines what the proxy is allowed to do on behalf of the real account. It describes the capabilities of that proxy (e.g., staking-only, governance-only, transfer-only, etc.). + +The following table shows the available `ProxyType` options and their descriptions: + +| `ProxyType` | Description | +| ------------------------ | ----------------------------------------------------------------------------------- | +| `Any` | Grants full permissions. This is the most permissive `ProxyType`; use with caution. | +| `Owner` | Allows subnet owner operations. | +| `NonCritical` | Allows only non-critical operations. | +| `NonTransfer` | Blocks all transfer operations. | +| `Senate` | Allows senate governance operations. | +| `NonFungibile` (sic) | Blocks all TAO transfer or movement. | +| `Triumvirate` | Allows triumvirate governance operations. | +| `Governance` | Covers both senate and triumvirate governance operations. | +| `Staking` | Allows staking-related operations. | +| `Registration` | Allows registration-related operations. | +| `Transfer` | Allows unrestricted transfer operations. | +| `SmallTransfer` | Allows transfers capped at 0.5 TAO. | +| `ChildKeys` | Allows child key operations. | +| `SudoUncheckedSetCode` | Restricted to a single privileged call form. | +| `SwapHotkey` | Allows hotkey swap operations. | +| `SubnetLeaseBeneficiary` | Allows management of leased subnets. | + +See [source code: ProxyType enum definition](https://github.com/opentensor/subtensor/blob/main/common/src/lib.rs#L144-L162) and [source code: proxy filtering implementation](https://github.com/opentensor/subtensor/blob/main/runtime/src/lib.rs#L678-L884). + +### Choosing the Right `ProxyType` + +When setting up proxies, always follow the principle of least privilege. Choose the narrowest `ProxyType` that covers the intended actions instead of defaulting to broad permissions. For example: + +- Operational tasks: `Staking`, `Registration`, `ChildKeys`, `SwapHotkey`. +- Governance actions: `Triumvirate`, `Senate`, or `Governance` (broader). +- Funds movement: `Transfer` or `SmallTransfer` (with per-transfer limit). +- Subnet leasing: `SubnetLeaseBeneficiary`. + +Only use the unrestricted `Any` type when no other option fits. If a proxy call fails with `proxy.Unproxyable` or `system.CallFiltered`, it usually means the selected `ProxyType` doesn’t permit that call. In such cases, switch to a more suitable type or create a separate proxy with proper scope. + +## Proxy Usage Limits + +To ensure scalability and prevent abuse, proxy usage is subject to certain limits as shown: + +- **`MaxProxies`**: This refers to the maximum number of delegate accounts that can be linked to a single real account. Each account can register up to 20 proxies in total. See [source code: MaxProxies configuration](https://github.com/opentensor/subtensor/blob/main/runtime/src/lib.rs#L670). +- **`MaxPending`**: This refers to the maximum number of pending announcements that a delegate account can have. This limit helps prevent excessive queuing. Each account can have up to 75 pending announcements at a time. See [source code: MaxPending configuration](https://github.com/opentensor/subtensor/blob/main/runtime/src/lib.rs#L671). + +## Best practices for using proxies + +When setting up and using proxies, it’s important to follow practices that reduce security risks and operational overhead. The following guidelines highlight how to map permissions correctly, manage delays, and keep accounts secure while making proxy usage efficient: + +- Map your operational needs to a minimal `ProxyType`. If a type seems overly broad, consider whether a more restrictive variant exists. +- Use non-zero delays for high-risk actions; monitor announcements. +- Track deposits and limits; batch or clear announcements to avoid dangling deposits. +- Keep the real account cold; use the delegate hot account operationally. diff --git a/docs/keys/proxies/pure-proxies.md b/docs/keys/proxies/pure-proxies.md new file mode 100644 index 0000000000..bb0d0faa56 --- /dev/null +++ b/docs/keys/proxies/pure-proxies.md @@ -0,0 +1,119 @@ +# Understanding Pure Proxies + +Pure proxies are a specialized type of proxy account in Bittensor that provide enhanced security and isolation for complex delegation scenarios. Unlike standard proxies that use existing accounts, pure proxies create new, keyless accounts that can only operate through their delegator relationship. + +This page walks you through creating a pure proxy account, executing a transfer through it, and eventually removing it using the Polkadot.js web app. You will set up a new delegate account, add it to your Polkadot.js accounts, and use it to execute transactions on the blockchain. + +## Overview of pure proxies + +Pure proxies are **keyless, non-deterministic accounts** that are created fresh using the `createPure` extrinsic. They represent a unique approach to account delegation where: + +- The proxy account has **no private key** and cannot sign transactions independently +- The proxy can **only act through its delegator**—all operations must be initiated by the delegator +- The account is **completely isolated** and cannot escalate its own permissions + +Unlike standard proxies, where the delegate can access the delegator’s funds to execute calls on their behalf, pure proxies operate differently. A pure proxy account must hold its own funds, while the real account acts as an _any proxy_ for it—signing and authorizing transactions on the proxy’s behalf. + +:::info When to use pure proxies +Pure proxies are valuable when you want to keep your real account secure by reducing direct key exposure to the blockchain. They provide a keyless, flexible account that enables permissionless management and are especially effective for multisigs, since they allow updates to membership or thresholds without changing the account address. +::: + +## Transaction flow in pure proxies + +All transactions involving a pure proxy must be signed by the delegator account. Once signed, the transaction is executed on-chain as if it originated directly from the pure proxy. Unlike standard proxies, a pure proxy must hold its own funds to cover fees or transfers. The delegator then acts as an _any proxy_, handling the signing and authorization of calls, but the balance used comes from the pure proxy's account. + +When submitting calls with the `proxy(real, forceProxyType, call)` extrinsic, the pure proxy account is passed as the `real` argument, while the delegator signs the transaction. This effectively reverses the usual proxy relationship where the proxy account only authorizes the transaction, while the real account appears as the origin on chain. + +:::info +You can modify who signs for a pure proxy by assigning another account as its _any proxy_. This is done by executing a proxy call that creates a standard proxy with the `Any` proxy type. The new account can then sign on behalf of the pure proxy—for example, when updating signers in a multisig wallet. See [source code: pure proxy account generation](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L827-L850). +::: + +## Prerequisites + +- A locally running subtensor development chain. For more information, see [run a local Bittensor blockchain instance](../../local-build/deploy.md). +- [Polkadot‑JS browser app](https://polkadot.js.org/apps/?#/explorer) connected to your local Bittensor instance and [Polkadot‑JS browser extension](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd) installed. For information on connecting the Polkadot-JS browser app to your local blockchain instance, see [Connect Polkadot to your local chain](./create-proxy.md#step-1-connect-polkadotjs-to-your-local-chain). +- An accessible 'Alice' wallet. For more information, see [Provision Wallets for Local Deploy](../../local-build/provision-wallets). +- At least 2 different accounts in your Polkadot-JS app: + - Real (delegator) account that controls funds and adds the proxy. + - A recipient account to receive transferred funds. + +## Create a pure proxy + +Use the `proxy::createPure` extrinsic to create a pure proxy as shown. See [source code: `createPure` implementation](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L328-L360): + +1. In the navbar menu, navigate to **Developers** → **Extrinsics**. +2. Under “using the selected account”, pick the delegator account. +3. Under “submit the following extrinsic”, choose the `proxy` pallet and call `createPure(proxyType, delay, index)`. +4. Fill the parameters: + + - `proxyType`: select `Any`; this grants full permissions to the proxy, including the ability to make transfers and kill the proxy. + - `delay`: optionally, include a delay in blocks. + - `index`: leave as zero. + +5. Click **Submit Transaction** and sign with the _delegator_ account. + +### Retrieve and import the proxy account + +1. After creating the pure proxy, go to **Network** → **Explorer** in the Polkadot-JS web app. +2. On the **recent events** panel, find the `proxy.PureCreated` event from the transaction. This event shows details of the proxy created including the address of the newly spawned account. +3. Copy the address of the proxy account. +4. Go to **Accounts** → **Accounts**. +5. Click **+ Proxied**. +6. Paste the proxy account address in the **proxied account** field and then provide a name for the pure proxy account. + +Importing the proxy account makes it selectable in the Polkadot-JS web app UI. + +:::tip + +- Record the block number and extrinsic index where the pure proxy was created. These values are required when removing the proxy. +- When creating a proxy on mainnet, you can check block details on the [Tao.app block explorer page](https://www.tao.app/blocks). + +::: + +## Executing calls via a pure proxy + +1. Go to **Developer** → **Extrinsics**. +2. Under “using the selected account”, choose the delegate account—account that created the proxy. +3. Select the `proxy` pallet and choose `proxy(real, forceProxyType, call)`. +4. Fill the parameters: + - `real`: select the pure proxy account from the UI. + - `forceProxyType`: leave option unchecked. + - `call`: the call to be made by the delegate account. Fill the following parameters: + - Select the `balances` pallet and choose the `transferKeepAlive(dest, value)` extrinsic. + - `dest`: select the recipient account. + - `value`: input the amount to be transferred in RAO—1 TAO = 19RAO. +5. Click **Submit Transaction** and sign the transaction from the delegate account. + +:::info + +- After submitting the transaction, check the Polkadot.JS web app's **Explorer** page for a `balances.Transfer` event. Notice the sender is the pure proxy account. +- Ensure the pure proxy account holds enough funds to cover both the transfer and associated fees. + ::: + +### Kill a pure proxy + +Pure proxies are killed using the `killPure` extrinsic as shown. See [source code: `killPure` implementation](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L380-L406): + +1. Go to **Developer** → **Extrinsics**. +2. Under “using the selected account”, choose the pure proxy account. +3. Select the `proxy` pallet and choose `killPure(spawner, proxyType, index, height, extIndex)`. +4. Fill the parameters: + - `spawner`: select the account that created the proxy from the UI. + - `proxyType`: select the proxy type. + - `index`: leave as `0`. + - `height`: input the block number that the proxy was created at. + - `extIndex`: input the extrinsic index of the `proxy.PureCreated` event. +5. Click **Submit Transaction** and sign the transaction from the delegate account. + +Ensure that all parameters are correct before making this call. The call will fail with a `Proxy.NoPermission` error if any parameter is invalid or if the origin account lacks permission to perform the action. + +:::info Removing vs. Killing a Pure Proxy +Killing a pure proxy permanently deletes the account and releases its reserved deposit. Removing a proxy, on the other hand, only detaches it from the account that initiates the transaction. The pure proxy remains on-chain and can still be used if it has other proxies linked to it, but it becomes inactive once all proxy relationships are removed. For more information on how to remove a proxy, see [Remove a proxy](create-proxy.md#step-4-remove-a-proxy). +::: + +## Troubleshooting + +- `Token.FundsUnavailable`: Ensure that the pure proxy account has been funded and has enough funds to cover the transfer. +- `proxy.NotProxy`: Ensure you're executing the pure proxy correctly—from the creator account and referencing the pure proxy account as `real`. See [source code: `NotProxy` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L735). +- `Proxy.NoPermission`: The `killPure` call is not permitted under the current. See [source code: `NoPermission` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L741). +- `system.CallFiltered`: The call is not permitted under the current `ProxyType`. diff --git a/docs/subnets/schedule-coldkey-swap.md b/docs/keys/schedule-coldkey-swap.md similarity index 60% rename from docs/subnets/schedule-coldkey-swap.md rename to docs/keys/schedule-coldkey-swap.md index 7e4455001f..c294592d79 100644 --- a/docs/subnets/schedule-coldkey-swap.md +++ b/docs/keys/schedule-coldkey-swap.md @@ -7,30 +7,25 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; # Rotate/Swap your Coldkey -This page describes how to *rotate* or *swap* the coldkey in your wallet. This is required if you suspect your coldkey has been leaked. Your coldkey secures your identity on Bittensor. +This page describes how to _rotate_ or _swap_ the coldkey in your wallet. This is required if you suspect your coldkey has been leaked. Your coldkey secures your identity on Bittensor. See: -- [Wallets, Coldkeys and Hotkeys in Bittensor](../getting-started/wallets) -- [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security) - - -## Description - -The `btcli` command does not yet support this schedule coldkey swap feature. You must use the [Polkadot JS extension](https://polkadot.js.org/extension/). +- [Wallets, Coldkeys and Hotkeys in Bittensor](./wallets) +- [Coldkey and Hotkey Workstation Security](./coldkey-hotkey-security) See [code for coldkey swap](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/swap/swap_coldkey.rs). The schedule coldkey swap feature works as follows: - The schedule coldkey swap feature enables you to schedule the swapping of source coldkey to a destination coldkey. If you feel your existing coldkey is potentially compromised, then use this feature to schedule a swap to a destination coldkey. -- When you use this feature, it will not immediately swap your coldkeys and swap your TAO funds from the source coldkey to the destination coldkey. It will only schedule the swap event. -- All scheduled coldkey swaps will be executed on-chain. **Your scheduled coldkey swap will execute on the mainnet exactly 5 days after you successfully scheduled the coldkey swap using the method described in this document.** -- The source coldkey you used in this method will be locked when you schedule the swap. After the 5-day period is elapsed your original coldkey will be unlocked entirely. +- When you use this feature, it will not immediately swap your coldkeys and swap your TAO funds from the source coldkey to the destination coldkey. It will only schedule the swap event. +- All scheduled coldkey swaps will be executed on-chain. **Your scheduled coldkey swap will execute on the mainnet 7200 blocks (approximately 24 hours) after you successfully scheduled the coldkey swap using the method described in this document.** +- The source coldkey you used in this method will be locked when you schedule the swap. After the 7200-block period is elapsed your original coldkey will be unlocked entirely. - **Cost**: The cost of this coldkey swap transaction is 0.1 TAO. This must be available in your source coldkey. - Any subnet ownership from your source coldkey will move to the destination coldkey. - The delegated stake will be transferred from your source coldkey to the destination coldkey. -- For those who were staking to a validator from their source coldkey, their staking TAO will transfer to the destination coldkey. +- For those who were staking to a validator from their source coldkey, their staking TAO will transfer to the destination coldkey. :::danger Do not schedule coldkey swap more than once using the same coldkey ::: @@ -38,18 +33,24 @@ The schedule coldkey swap feature works as follows: ## Requirements 1. To execute this operation, you must own the source coldkey. -1. The destination (new) coldkey public key must not already be assigned to a hotkey *or a coldkey that is associated with any hotkeys*. -1. Confirm the identity of the destination coldkey. A mistake here can result in loss of all of the source coldkey's assets and identity. - - If you are rotating the coldkey to maintain ownership, you must control the destination coldkey privatekey. Otherwise you will lose control over all of the source coldkey's assets and identity. - - If you are transferring ownership to someone else, confirm that they have secure control of the destination coldkey private key. -2. You must use the [Polkadot JS extension](https://polkadot.js.org/extension/). The `btcli` command does not yet support scheduling coldkey swap. -3. You must import your source and destination coldkeys into the Polkadot JS extension. -4. You must connect the source coldkey account to the [polkadot.js.org/apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer) website. +2. The destination (new) coldkey public key must not already be assigned to a hotkey _or a coldkey that is associated with any hotkeys_. +3. Confirm the identity of the destination coldkey. A mistake here can result in loss of all of the source coldkey's assets and identity. + - If you are rotating the coldkey to maintain ownership, you must control the destination coldkey privatekey. Otherwise you will lose control over all of the source coldkey's assets and identity. + - If you are transferring ownership to someone else, confirm that they have secure control of the destination coldkey private key. + +## Using Bittensor-CLI - :::danger If you do not do this step, then you will not see **Developer** > **Extrinsics** option on the [polkadot.js.org/apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/extrinsics) website. - ::: +`btcli w swap-coldkey` + +## Using the [Polkadot JS extension](https://polkadot.js.org/extension/) + +1. You must import your source and destination coldkeys into the Polkadot JS extension. +2. You must connect the source coldkey account to the [polkadot.js.org/apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer) website. + +:::danger If you do not do this step, then you will not see **Developer** > **Extrinsics** option on the [polkadot.js.org/apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/extrinsics) website. +::: -## Steps +## Steps for Polkadot JS Follow the steps shown below the screenshot: @@ -72,7 +73,7 @@ Open your web browser and navigate to the Polkadot.js Apps website (https://polk ### Step 2: Navigate to the Extrinsics page -From the top navigation menu, proceed to **Developer** > **Extrinsics** to open the Extrinsics page. If you do not see this option, then make sure you successfully imported your source coldkey into the Polkadot JS extension, and connected this source coldkey account to the Polkadot.js Apps website. +From the top navigation menu, proceed to **Developer** > **Extrinsics** to open the Extrinsics page. If you do not see this option, then make sure you successfully imported your source coldkey into the Polkadot JS extension, and connected this source coldkey account to the Polkadot.js Apps website. ### Step 3: Select your source coldkey account @@ -82,20 +83,20 @@ Locate the drop-down section labeled **using the selected account** and select y Locate the drop-down section labeled **submit the following extrinsic** and select `subtensorModule`. -### Step 5: Choose the `scheduleSwapColdkey` function +### Step 5: Choose the `scheduleSwapColdkey` function -After selecting the `subtensorModule`, a second drop-down menu will appear on the right side of it. From this drop-down select the `scheduleSwapColdkey` option. +After selecting the `subtensorModule`, a second drop-down menu will appear on the right side of it. From this drop-down select the `scheduleSwapColdkey` option. -### Step 6: Provide the destination coldkey +### Step 6: Provide the destination coldkey Provide your destination coldkey in the `newColdkey: AccountId32` field. ### Step 7: Submit the transaction -Check again that you have provided the correct source and destination coldkeys. +Check again that you have provided the correct source and destination coldkeys. Scroll down to the bottom of the page and click on the **Submit Transaction** button. Polkadot.js will prompt you to sign the transaction using the selected account. After you sign the transaction, the signed transaction will be broadcast to the Subtensor. ## Verify -Your scheduled coldkey swap will execute on the mainnet 5 days after you successfully scheduled the coldkey swap using the above method. Check your destination coldkey after 5 days to verify. +Your scheduled coldkey swap will execute on the mainnet 7200 blocks after you successfully scheduled the coldkey swap using the above method. Check your destination coldkey after approximately 24 hours to verify. diff --git a/docs/getting-started/wallets.md b/docs/keys/wallets.md similarity index 75% rename from docs/getting-started/wallets.md rename to docs/keys/wallets.md index 87264299b8..0d391a6418 100644 --- a/docs/getting-started/wallets.md +++ b/docs/keys/wallets.md @@ -1,31 +1,32 @@ --- title: "Wallets, Coldkeys and Hotkeys in Bittensor" --- + import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; # Wallets, Coldkeys and Hotkeys in Bittensor -In Bittensor (like other cryptocurrency applications), a *wallet* is a tool for proving your identity, signing transactions, accessing your TAO, and managing your stake in subnets. +In Bittensor (like other cryptocurrency applications), a _wallet_ is a tool for proving your identity, signing transactions, accessing your TAO, and managing your stake in subnets. This page introduces the core concepts involved. -For detailed procedures for handling wallets and keys, see: [Working with keys](../working-with-keys.md) +For detailed procedures for handling wallets and keys, see: [Working with keys](./working-with-keys.md) For detailed security considerations, see: [Coldkey and Hotkey Workstation Security](./coldkey-hotkey-security.md) ## What are wallets and keys? -There are many different *wallet applications*, but the core of your wallet is one or more cryptographic key-pairs, referred to as **coldkey** and **hotkey**. +There are many different _wallet applications_, but the core of your wallet is one or more cryptographic key-pairs, referred to as **coldkey** and **hotkey**. Each is actually a cryptographic [key-pair](https://en.wikipedia.org/wiki/Public-key_cryptography), a private and a public key. The public key is mathematically derived from the private key. The private key is a closely held secret: it allows the owner to sign transactions and decrypt secrets, essentially serving as a cryptographic authentication or identity. -This is a general feature of decentralized, trustless systems like distributed ledgers/blockchains: your private key *is* your identity, in that theft or loss of your key results in *unrecoverable* loss of access. +This is a general feature of decentralized, trustless systems like distributed ledgers/blockchains: your private key _is_ your identity, in that theft or loss of your key results in _unrecoverable_ loss of access. In Bittensor, the coldkey and hotkey are used for different operations. In short, the hotkey is for mining and validation, and the coldkey for everything else; if you neither mine nor validate, you have no need for a hotkey, but you will identify validators and miners by their hotkey public keys. The coldkey private key is needed to authorize highly sensitive operations involved in transferring TAO balances and managing stake, operations related to subnet management and governance, and management of hotkeys. The hotkey private key is needed to authorize miners to serve requests in subnets, and by validators to send requests to miners and to submit weights to the blockchain. -The coldkey public key identifies a wallet to the internet, serving as an address. To transfer ownership of TAO or alpha stake from one wallet to another, the sender needs only the public key of the recipient, and their own private key. +The coldkey public key uniquely identifies a wallet on the network and serves as its address for transactions. To transfer ownership of TAO or alpha stake from one wallet to another, the sender needs only the public key of the recipient, and their own private key. ## Wallets and wallet applications @@ -36,38 +37,39 @@ We must be careful to distinguish two senses of the term 'wallet' that can other - The **wallet application** is software that runs on your device and allows you to interact with the blockchain by entering your keys. There are several officially supported Bittensor wallet applications: - The Bittensor wallet app for mobile: [bittensor.com/wallet](https://bittensor.com/wallet) - - [The Polkadot browser extension](https://polkadot.js.org/extension/) which can be used with Polkadot Vault... - + - [The Crucible wallet](https://cruciblelabs.com) a Tao wallet featuring an auto-allocator for dynamic TAO staking across subnets, with full Ledger integration. + - [The Polkadot browser extension](https://polkadot.js.org/extension/) which can be used with Polkadot Vault. + - [The Bitensor wallet browser extension](https://chromewebstore.google.com/detail/bittensor-wallet/bdgmdoedahdcjmpmifafdhnffjinddgc), which is also compatible with use of a Ledger hardware wallet. See [Using Ledger Hardware Wallet](../staking-and-delegation/using-ledger-hw-wallet.md) Using the Bittensor wallet browser extension, you can [use TAO.app to manage stake](https://tao.app). - The Bittensor Python SDK, which includes the secure [Bittensor Wallet module](https://docs.bittensor.com/btwallet-api/html/autoapi/btwallet/wallet/index.html). - - The Bittensor CLI, `btcli`, which uses the Bittensor Wallet module under the hood. + - The Bittensor CLI, `btcli`, which uses the Bittensor Wallet module under the hood. -Every Bittensor user has one or more cryptographic wallets, i.e. one or more coldkey. Any cryptographic wallet can be loaded into any number of wallet applications. If every wallet application that has been initialized with your cryptographic wallet (i.e. signed into with your coldkey private key) is closed, logged out, etc., and the device incinerated, your cryptographic wallet exists on the blockchain, and can be recovered with your *seed phrase*. +Every Bittensor user has one or more cryptographic wallets, i.e. one or more coldkey. Any cryptographic wallet can be loaded into any number of wallet applications. If every wallet application that has been initialized with your cryptographic wallet (i.e. signed into with your coldkey private key) is closed, logged out, etc., and the device incinerated, your cryptographic wallet exists on the blockchain, and can be recovered with your _seed phrase_. Different wallet applications have different levels of functionality: - The mobile app and Chrome extension allow for staking and transfer of TAO balalnces, but do not include any hotkey management or advanced functionality. - - Note that the Chome extension is compatible with a hardware wallet, which can be a strong security option. This implies using a laptop as your [coldkey workstation](../getting-started/coldkey-hotkey-security). + - Note that the Chome extension is compatible with a hardware wallet, which can be a strong security option. This implies using a laptop as your [coldkey workstation](./coldkey-hotkey-security). - - The mobile app depends on using a secure phone as a [coldkey workstation](../getting-started/coldkey-hotkey-security). + - The mobile app depends on using a secure phone as a [coldkey workstation](./coldkey-hotkey-security). -- `btcli` and the SDK allow for hotkey management and other advanced functionality. These require a laptop as a [coldkey workstation](../getting-started/coldkey-hotkey-security). +- `btcli` and the SDK allow for hotkey management and other advanced functionality. These require a laptop as a [coldkey workstation](./coldkey-hotkey-security). :::tip Note that you can also check balances on an unsecure device without entering your coldkey private key. For example, using [https://bittensor.com/scan](https://bittensor.com/scan). These website can be considered permissionless wallet applications. -See [Coldkey and Hotkey Workstation Security: Permissionless workstation](../getting-started/coldkey-hotkey-security#permissionless-workstation) +See [Coldkey and Hotkey Workstation Security: Permissionless workstation](./coldkey-hotkey-security#permissionless-workstation) ::: ## The seed phrase a.k.a. mnemonic -The ***seed phrase*** (a.k.a. 'menemonic' or 'recovery phrase') is a series of (at least 12) words that is generated together with your wallet's cryptographic key pair, and which can be used to recover the coldkey private key. This seed phrase is therefore a human-usable way to save access to the cryptographic wallet offline, and to import the cryptographic wallet into a wallet application. +The **_seed phrase_** (a.k.a. 'menemonic' or 'recovery phrase') is a series of (at least 12) words that is generated together with your wallet's cryptographic key pair, and which can be used to recover the coldkey private key. This seed phrase is therefore a human-usable way to save access to the cryptographic wallet offline, and to import the cryptographic wallet into a wallet application. -Arguably the most important operational goal when handling Bittensor wallets is to avoid losing or leaking your seed phrase. Make sure you [Handle your Seed Phrase/Mnemonic Securely](../keys/handle-seed-phrase). +Arguably the most important operational goal when handling Bittensor wallets is to avoid losing or leaking your seed phrase. Make sure you [Handle your Seed Phrase/Mnemonic Securely](./handle-seed-phrase). ## Wallet applications @@ -86,9 +88,11 @@ In theory this means that without your encryption password, it is impossible to However, still consider that using your coldkey on a device offers other ways for attackers to steal your key, even without decrypting it. See [Coldkey workstation security](./coldkey-hotkey-security#coldkey-workstation). -Secure wallet apps supported by Opentensor Foundation include: -- The Bittensor wallet app for mobile: [bittensor.com/wallet](https://bittensor.com/wallet) -- [The Chrome extension](https://chromewebstore.google.com/detail/bittensor-wallet/bdgmdoedahdcjmpmifafdhnffjinddgc), which is also compatible with use of a Ledger hardware wallet. See [Using Ledger Hardware Wallet](../staking-and-delegation/using-ledger-hw-wallet.md) +Secure wallet apps include: + +- The Bittensor wallet app for mobile, by Opentensor Foundation: [bittensor.com/wallet](https://bittensor.com/wallet) +- [The Chrome extension](https://chromewebstore.google.com/detail/bittensor-wallet/bdgmdoedahdcjmpmifafdhnffjinddgc), which is also compatible with use of a Ledger hardware wallet, by Opentensor Foundation. See [Using Ledger Hardware Wallet](../staking-and-delegation/using-ledger-hw-wallet.md) +- [The Crucible wallet](https://cruciblelabs.com) by Crucible Labs a Tao wallet featuring an auto-allocator for dynamic TAO staking across subnets, with full Ledger integration. ### `btcli` and the Bittensor Python SDK @@ -101,18 +105,17 @@ The Bittensor Command Line Interface (BTCLI) and Bittensor Python SDK offer more ## Coldkey details -In `btcli`, the coldkey is equivalent to the wallet name. For example, the `--wallet.name` option in a `btcli` command always accepts only `` as its value and the `--wallet.hotkey` option only accepts `` as its value. +In `btcli`, the coldkey is equivalent to the wallet name. For example, the `--wallet.name` option in a `btcli` command always accepts only `` as its value and the `--wallet.hotkey` option only accepts `` as its value. This is because the coldkey holds the permissions and ownership over multiple hotkeys on-chain; hence, the wallet name is assigned to the coldkey. -**Relationship to hotkey**: A coldkey can exist without a hotkey or have multiple hotkeys. For example, to create a subnet, delegate stake, or simply hold balance you only need a coldkey. However, if you want to validate or mine in a subnet, you need a hotkey paired with this coldkey. +**Relationship to hotkey**: A coldkey can exist without a hotkey; it can also have multiple hotkeys. For example, to create a subnet, delegate stake, or simply hold balance you only need a coldkey. However, if you want to validate or mine in a subnet, you need a hotkey paired with this coldkey. **Purpose**: A coldkey is required for all operations that affect balances, such as transfer of TAO, staking and unstaking. It is also required for creating and registering hotkeys, and for subnet management and governance functions. -**Encryption**: A coldkey is only stored on your disk in encrypted form, and requires an encryption password. - -See [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security) for concrete security details about working with coldkeys. +**Encryption**: A coldkey is only stored on your disk in an encrypted form, and requires an encryption password. +See [Coldkey and Hotkey Workstation Security](./coldkey-hotkey-security) for concrete security details about working with coldkeys. + +## Neuron-to-neuron communication + +Neurons exchange information by: + +- Encapsulating the information in a Synapse object. +- Instantiating the server (Axon) and client (dendrite) network elements and exchanging Synapse objects using this server-client (Axon-dendrite) protocol. See the below diagram. + +
+ +
+ +### Axon + +The `axon` module in the Bittensor API uses the FastAPI library to create and run API servers. For example, when a subnet miner calls, + +```python +axon = bt.axon(wallet=self.wallet, config=self.config) +``` + +then an API server with the name `axon` is created on the subnet miner node. This `axon` API server receives incoming Synapse objects from subnet validators, i.e., the `axon` starts to serve on behalf of the subnet miner. + +Similarly, in your subnet miner code you must use the `axon` API to create an API server to receive incoming Synapse objects from the subnet validators. + +### Dendrite + +Axon is a **server** instance. Hence, a subnet validator will instantiate a `dendrite` **client** on itself to transmit information to axons that are on the subnet miners. For example, when a subnet validator runs the following code fragment: + +```python + responses: List[bt.Synapse] = await self.dendrite( + axons=axons, + synapse=synapse, + timeout=timeout, + ) +``` + +then the subnet validator: + +- Instantiates a `dendrite` client on itself. +- Transmits `synapse` objects to a set of `axons` (that are attached to subnet miners). +- Waits until `timeout` expires. + +### Synapse + +A synapse is a data object. Subnet validators and subnet miners use Synapse data objects as the main vehicle to exchange information. The `Synapse` class inherits from the `BaseModel` of the Pydantic data validation library. + +For example, in the [Text Prompting Subnet](https://github.com/macrocosm-os/prompting/blob/414abbb72835c46ccc5c652e1b1420c0c2be5c03/prompting/protocol.py#L27), the subnet validator creates a `Synapse` object, called `PromptingSynapse`, with three fields—`roles`, `messages`, and `completion`. The fields `roles` and `messages` are set by the subnet validator during the initialization of this Prompting data object, and they cannot be changed after that. A third field, `completion`, is mutable. When a subnet miner receives this Prompting object from the subnet validator, the subnet miner updates this `completion` field. The subnet validator then reads this updated `completion` field. + +## The Metagraph + +The metagraph is a data structure that contains comprehensive information about current state of the subnet. When you inspect the metagraph of a subnet, you will find detailed information on all the nodes (neurons) in the subnet. A subnet validator should first sync with a subnet's metagraph to know all the subnet miners that are in the subnet. The metagraph can be inspected without participating in a subnet. + +See [The Subnet Metagraph](../subnets/metagraph) diff --git a/docs/learn/price-protection.md b/docs/learn/price-protection.md new file mode 100644 index 0000000000..2cf603d849 --- /dev/null +++ b/docs/learn/price-protection.md @@ -0,0 +1,496 @@ +--- +title: "Understand Price Protection" +--- + +# Understand Price Protection + +## Price Protection Modes + +Bittensor clients (BTCLI and the SDK) provides three modes to give users control over how their transactions handle adverse price movements: Strict, Partial, and Unsafe. + +Other users' transactions can affect the token price, even while your transaction is pending. Subnet token prices may change rapidly, with significant consequences affecting your execution price and increasing slippage. These effects can be exploited by "sandwich attacks", or can result in loss of liquidity due to organic price volatility. + +It is therefore important to carefully manage price protection when staking and unstaking real value liquidity, i.e. on mainnet ("finney"). + +### Strict Safe Mode (Default) + +In this mode, the transaction is **rejected entirely** if executing it would push the final market price beyond the tolerance threshold from the price when you submitted the transaction. Tolerance threshold can be specified but is 5% by default. + +This mode provides maximum protection against price volatility, market movements, and sandwich attacks by preventing transactions that would push the execution price beyond the specified tolerance. This is preferable when you want to guarantee a transaction price, and are willing to accept transaction failure if you cannot get that price. + +**Example**: You set a 2% tolerance for unstaking. If executing your transaction would push the final price more than 2% below the price when you submitted the transaction, the entire transaction is rejected. + +### Partial Safe Mode + +In this mode, the transaction executes **the maximum amount that can be executed while keeping the execution price within the defined tolerance** of the original submission price. If the full amount would cause the market price to exceed the tolerance range, only a portion would be executed. + +This mode ensures a partial transaction execution even if market conditions would make the full transaction exceed price tolerance limits. + +This is preferable if you want a guarantee of some transaction, and are willing to accept variation in price, which can result in loss of liquidity of up to the tolerance threshold. + +**Example**: You try to unstake 1000 alpha with 2% tolerance. If executing the full amount would push the final market price beyond 2% of the original price, the system calculates and executes only the maximum amount (e.g., 400 alpha) that stays within the 2% limit. + +### Unsafe Mode + +This mode **ignores price protection entirely**. The transaction executes regardless of price movements, offering the fastest execution but no protection against adverse price changes or sandwich attacks. + +This mode is generally convenient for development and testing, but inadvisable with real-value liquidity on mainnet ("finney"). + +### Example Comparison by Mode + +Consider attempting to unstake 1000 alpha when executing the full transaction would push the market price 5% below the original price, with tolerance set to 2%: + +| Mode | Outcome | +|------|---------| +| Strict Safe | Transaction rejected entirely (5% price movement > 2% tolerance) | +| Partial Safe | Unstakes ~400 alpha (maximum amount that keeps final price within 2% tolerance) | +| Unsafe | Unstakes full 1000 alpha regardless of 5% price impact | + + +## Managing Price Protection with BTCLI + +The `btcli stake` interface provides parameters to control price protection modes. + +**Enable/disable price protection (strict or partial):** + +True by default. Enables price protection, which is strict by default. + +```bash +--safe-staking/--no-safe-staking, --safe/--unsafe +``` + +**Enable/disable partial execution (ignored in unsafe mode):** + +If price protection (`--safe-staking`) is enabled, determines whether protection is strict or partial. + +```bash +--allow-partial-stake/--no-allow-partial-stake, --partial/--no-partial +``` + +**Set price tolerance:** + +If in **partial safe** staking mode, determines the threshold of price variation tolerated in the transaction. +```bash +--tolerance, --rate-tolerance FLOAT +``` + +- **Default**: 0.005 (0.5%) +- **Range**: 0.0 to 1.0 (0% to 100%) +- **Purpose**: Maximum allowed final price deviation from submission price + +### BTCLI Examples + +**Strict Safe Mode (reject if price moves beyond tolerance):** +```bash +# note that --safe is unnecessary as it is enabled by default +btcli stake add --amount 100 --netuid 1 --safe --tolerance 0.02 --no-partial +``` + +**Partial Safe Mode (execute what fits within tolerance):** +```bash +# note that --safe is unnecessary as it is enabled by default +btcli stake add --amount 1000 --netuid 1 --safe --tolerance 0.02 --partial +``` + +**Unsafe Mode (ignore price protection):** +```bash +btcli stake add --amount 300 --netuid 1 --unsafe +``` + +## Managing Price Protection with SDK + +The Bittensor SDK provides price protection through method parameters: + +### Parameters + +:::warning +Unlike the `btcli`, the SDK's default behavior is *Unsafe* mode. +You must explicitly configure price protection when using the SDK's staking/unstaking functionality. +::: + +**`safe_staking`** (bool): +- **Default**: False +- **Purpose**: Enables price protection + +**`allow_partial_stake`** (bool): +- **Default**: False +- **Purpose**: Enables partial execution mode + +**`rate_tolerance`** (float): +- **Default**: 0.005 (0.5%) +- **Range**: 0.0 to 1.0 +- **Purpose**: Maximum allowed final price deviation from submission price + +### SDK Examples + +See [Price Protection Simulation](#price-protection-simulation) for an extended example. + +#### Safe Mode (reject if price moves beyond tolerance) +```python +import bittensor as bt + +subtensor = bt.Subtensor() +wallet = bt.Wallet("my_wallet") + +success = subtensor.add_stake( + wallet=wallet, + hotkey_ss58="5F...", + netuid=1, + amount=bt.Balance.from_tao(100), + safe_staking=True, # Enable protection + rate_tolerance=0.02, # 2% price tolerance + allow_partial_stake=False # Reject if exceeds tolerance +) +``` + +#### Partial Mode (execute what fits within tolerance) +```python +success = subtensor.add_stake( + wallet=wallet, + hotkey_ss58="5F...", + netuid=1, + amount=bt.Balance.from_tao(1000), + safe_staking=True, # Enable protection + rate_tolerance=0.02, # 2% price tolerance + allow_partial_stake=True # Execute partial amount within tolerance +) +``` + +#### Unsafe Mode (ignore price protection) +```python +success = subtensor.add_stake( + wallet=wallet, + hotkey_ss58="5F...", + netuid=1, + amount=bt.Balance.from_tao(100), + safe_staking=False # Disable protection; Unnecessary as this is the default setting +) +``` + +## Price Protection Simulation + +The following script runs through several different stake and unstake operations with different price protection modes, to demonstrate the different behaviors contingent on price. + +Prerequisites: +- [Run a Local Bittensor Blockchain Instance](../local-build/deploy) +- [Create a subnet on a local blockchain](../local-build/create-subnet) + +:::tip troubleshooting tip +If you see `Custom error: 14` you may need to start emissions on your subnet with +```shell +btcli s start +``` +::: + +```python +import bittensor as bt + +def display_balances_and_stakes(subtensor, wallet, target_hotkey, netuid, label): + """Display current balances and stakes for the simulation.""" + print(f"\n--- {label} ---") + balance = subtensor.get_balance(wallet.coldkey.ss58_address) + stakes = subtensor.get_stake_for_coldkey(wallet.coldkey.ss58_address) + + print(f"Coldkey balance: {balance}") + + # Find stake for our target hotkey and netuid + target_stake = None + for stake_info in stakes: + if stake_info.hotkey_ss58 == target_hotkey and stake_info.netuid == netuid: + target_stake = stake_info.stake + break + + if target_stake: + print(f"Stake on {target_hotkey[:8]}... (netuid {netuid}): {target_stake}") + else: + print(f"No stake found on {target_hotkey[:8]}... (netuid {netuid})") + +def show_current_price_and_protection(subtensor, netuid, tolerance, label): + """Show current subnet price and calculate protection thresholds.""" + print(f"\n{label} Price Analysis:") + subnet_info = subtensor.subnet(netuid=netuid) + current_price = subnet_info.price + print(f"Current price: {current_price}") + + # Calculate protection thresholds + price_floor = current_price.tao * (1 - tolerance) + price_ceiling = current_price.tao * (1 + tolerance) + + print(f"Price protection with {tolerance:.2%} tolerance:") + print(f" • Price floor (unstaking): {price_floor:.6f} TAO/α") + print(f" • Price ceiling (staking): {price_ceiling:.6f} TAO/α") + print(f" • Protection range: {price_floor:.6f} - {price_ceiling:.6f} TAO/α") + + return subnet_info + +def demonstrate_protection_modes(): + """Comprehensive demonstration of all three price protection modes.""" + + print("=== Bittensor Price Protection Mode Simulation ===\n") + + # Connect to local network + subtensor = bt.Subtensor("ws://127.0.0.1:9945") + + # Get subnet information + netuid = 2 + subnet_info = subtensor.subnet(netuid=netuid) + if subnet_info is None: + print(f"Error: Could not connect to subnet {netuid}. Is the local node running?") + return False + + print(f"Connected to subnet {netuid}") + print(f"Alpha in reserve: {subnet_info.alpha_in}") + print(f"TAO in reserve: {subnet_info.tao_in}") + + # Initialize wallet + wallet = bt.wallet(name="Alice") + + try: + wallet.unlock_coldkey() + except Exception as e: + print(f"Error: Could not unlock wallet. Make sure 'Alice' wallet exists and is unlocked. {e}") + return False + + # Get registered hotkeys for the subnet + metagraph = subtensor.metagraph(netuid=netuid) + registered_hotkeys = metagraph.hotkeys + + if not registered_hotkeys: + print(f"Error: No registered hotkeys found on subnet {netuid}.") + return False + + target_hotkey = registered_hotkeys[0] + print(f"Using registered hotkey: {target_hotkey[:8]}...") + + # Display initial state + display_balances_and_stakes(subtensor, wallet, target_hotkey, netuid, "Initial State") + + print("\n" + "="*60) + print("SIMULATION: Testing price protection modes") + print("="*60) + + # Test amounts + stake_amount = 5.0 # TAO + + # Mode 1: UNSAFE MODE (No Protection) + print(f"\n{'='*20} MODE 1: UNSAFE (No Protection) {'='*20}") + print("Executes transaction regardless of price movements") + + subnet_info = show_current_price_and_protection(subtensor, netuid, 0.0, "Pre-Unsafe") + + try: + print(f"\nStaking {stake_amount} TAO with NO protection...") + success = subtensor.add_stake( + wallet=wallet, + hotkey_ss58=target_hotkey, + netuid=netuid, + amount=bt.Balance.from_tao(stake_amount), + safe_staking=False # No protection + ) + + if success: + print("✅ Unsafe staking successful") + else: + print("❌ Unsafe staking failed") + + except Exception as e: + print(f"❌ Unsafe staking failed: {e}") + + # Show price after unsafe transaction + show_current_price_and_protection(subtensor, netuid, 0.0, "Post-Unsafe") + + display_balances_and_stakes(subtensor, wallet, target_hotkey, netuid, "After Unsafe Staking") + + # Mode 2: SAFE MODE with VERY strict tolerance (should fail) + print(f"\n{'='*20} MODE 2: SAFE with STRICT Tolerance {'='*20}") + print("Rejects transaction if price moves beyond tolerance") + + strict_tolerance = 0.001 # 0.1% tolerance - very strict + large_stake_amount = 20.0 # Larger amount to trigger protection + + subnet_info = show_current_price_and_protection(subtensor, netuid, strict_tolerance, "Pre-Safe-Strict") + pre_safe_price = subnet_info.price.tao + price_ceiling = pre_safe_price * (1 + strict_tolerance) + + try: + print(f"\nStaking {large_stake_amount} TAO with SAFE protection (tolerance: {strict_tolerance:.2%})...") + print(f"Transaction should FAIL if final price > {price_ceiling:.6f} TAO/α") + + success = subtensor.add_stake( + wallet=wallet, + hotkey_ss58=target_hotkey, + netuid=netuid, + amount=bt.Balance.from_tao(large_stake_amount), + safe_staking=True, + rate_tolerance=strict_tolerance, + allow_partial_stake=False + ) + + if success: + print("❌ UNEXPECTED: Safe staking succeeded despite strict tolerance") + # Check if it should have failed + post_subnet_info = subtensor.subnet(netuid=netuid) + post_safe_price = post_subnet_info.price.tao + print(f"Final price: {post_safe_price:.6f} TAO/α") + print(f"Price ceiling was: {price_ceiling:.6f} TAO/α") + + if post_safe_price > price_ceiling: + print(f"🚨 BUG: Transaction succeeded but price ({post_safe_price:.6f}) > ceiling ({price_ceiling:.6f})") + else: + print(f"Price stayed within tolerance: {post_safe_price:.6f} ≤ {price_ceiling:.6f}") + print(f"Actual price increase: {((post_safe_price - pre_safe_price) / pre_safe_price) * 100:.3f}%") + else: + print("✅ EXPECTED: Safe staking failed due to strict tolerance") + + except Exception as e: + if "Price exceeded tolerance limit" in str(e) or "exceeded tolerance" in str(e) or "tolerance" in str(e).lower(): + print("🛡️ EXPECTED: Transaction rejected - price protection activated!") + else: + print(f"❌ Safe staking failed with unexpected error: {e}") + + # Show price after safe transaction + show_current_price_and_protection(subtensor, netuid, strict_tolerance, "Post-Safe-Strict") + + display_balances_and_stakes(subtensor, wallet, target_hotkey, netuid, "After Strict Safe Staking") + + # Mode 3: SAFE MODE with reasonable tolerance (should succeed) + print(f"\n{'='*20} MODE 3: SAFE with Reasonable Tolerance {'='*20}") + print("Demonstrating normal safe staking that succeeds") + + reasonable_tolerance = 0.05 # 5% tolerance + normal_amount = 5.0 # Normal amount + + subnet_info = show_current_price_and_protection(subtensor, netuid, reasonable_tolerance, "Pre-Safe-Normal") + + try: + print(f"\nStaking {normal_amount} TAO with SAFE protection (tolerance: {reasonable_tolerance:.2%})...") + + success = subtensor.add_stake( + wallet=wallet, + hotkey_ss58=target_hotkey, + netuid=netuid, + amount=bt.Balance.from_tao(normal_amount), + safe_staking=True, + rate_tolerance=reasonable_tolerance, + allow_partial_stake=False + ) + + if success: + print("✅ Safe staking successful with reasonable tolerance") + else: + print("❌ Safe staking failed") + + except Exception as e: + print(f"❌ Safe staking failed: {e}") + + display_balances_and_stakes(subtensor, wallet, target_hotkey, netuid, "After Normal Safe Staking") + + # Mode 4: PARTIAL MODE with strict tolerance (should execute partially) + print(f"\n{'='*20} MODE 4: PARTIAL with STRICT Tolerance {'='*20}") + print("Should execute maximum amount within tolerance") + + partial_strict_tolerance = 0.002 # 0.2% tolerance - very strict for partial + very_large_amount = 50.0 # Very large amount to force partial execution + + subnet_info = show_current_price_and_protection(subtensor, netuid, partial_strict_tolerance, "Pre-Partial-Strict") + + print(f"\nUsing very strict tolerance ({partial_strict_tolerance:.2%}) with large amount ({very_large_amount} TAO)") + print(f"Should execute PARTIAL amount to stay within tolerance") + + # Record balance before to see actual amount executed + balance_before = subtensor.get_balance(wallet.coldkey.ss58_address) + + try: + print(f"\nStaking {very_large_amount} TAO with PARTIAL protection (tolerance: {partial_strict_tolerance:.2%})...") + success = subtensor.add_stake( + wallet=wallet, + hotkey_ss58=target_hotkey, + netuid=netuid, + amount=bt.Balance.from_tao(very_large_amount), + safe_staking=True, + rate_tolerance=partial_strict_tolerance, + allow_partial_stake=True # Allow partial execution + ) + + # Check actual amount executed + balance_after = subtensor.get_balance(wallet.coldkey.ss58_address) + actual_amount_executed = balance_before.tao - balance_after.tao + + if success: + print("✅ Partial staking completed") + print(f"Amount requested: {very_large_amount} TAO") + print(f"Amount actually executed: {actual_amount_executed:.3f} TAO") + execution_percentage = (actual_amount_executed / very_large_amount) * 100 + print(f"Execution percentage: {execution_percentage:.1f}%") + + if actual_amount_executed < very_large_amount * 0.95: # Less than 95% executed + print(f"🎯 SUCCESS: PARTIAL execution detected! Only {execution_percentage:.1f}% executed due to price protection") + else: + print(f"🤔 Unexpected: Near-full execution despite strict tolerance") + else: + print("❌ Partial staking failed completely") + + except Exception as e: + print(f"❌ Partial staking failed: {e}") + + # Show price after partial to see impact + show_current_price_and_protection(subtensor, netuid, partial_strict_tolerance, "Post-Partial-Strict") + + display_balances_and_stakes(subtensor, wallet, target_hotkey, netuid, "After Partial Staking") + + # Demonstrate unstaking with protection + print(f"\n{'='*20} UNSTAKING WITH PROTECTION {'='*20}") + print("Demonstrating unstaking with price protection") + + # Find current stake to unstake from + stakes = subtensor.get_stake_for_coldkey(wallet.coldkey.ss58_address) + current_stake = None + for stake_info in stakes: + if stake_info.hotkey_ss58 == target_hotkey and stake_info.netuid == netuid: + current_stake = stake_info.stake + break + + if current_stake and current_stake.rao > 0: + unstake_tolerance = 0.05 # 5% tolerance for unstaking + subnet_info = show_current_price_and_protection(subtensor, netuid, unstake_tolerance, "Pre-Unstake") + + # Unstake a portion with protection + unstake_amount_rao = min(current_stake.rao // 4, int(50 * 1e9)) + unstake_balance = bt.Balance.from_rao(unstake_amount_rao).set_unit(netuid=netuid) + + print(f"Current stake: {current_stake}") + print(f"Attempting to unstake: {unstake_balance}") + + try: + print(f"\nUnstaking with SAFE protection (tolerance: {unstake_tolerance:.2%})...") + success = subtensor.unstake( + wallet=wallet, + hotkey_ss58=target_hotkey, + netuid=netuid, + amount=unstake_balance, + safe_staking=True, + rate_tolerance=unstake_tolerance, + allow_partial_stake=False + ) + + if success: + print("✅ Protected unstaking successful") + else: + print("❌ Protected unstaking failed") + + except Exception as e: + if "Price exceeded tolerance limit" in str(e) or "exceeded tolerance" in str(e): + print("🛡️ Unstaking rejected - price moved beyond tolerance") + else: + print(f"❌ Protected unstaking failed: {e}") + else: + print("No stake available to unstake") + + display_balances_and_stakes(subtensor, wallet, target_hotkey, netuid, "Final State") + show_current_price_and_protection(subtensor, netuid, 0.0, "Final") + + return True + +if __name__ == "__main__": + demonstrate_protection_modes() +``` \ No newline at end of file diff --git a/docs/learn/slippage.md b/docs/learn/slippage.md new file mode 100644 index 0000000000..d3fd3908d3 --- /dev/null +++ b/docs/learn/slippage.md @@ -0,0 +1,106 @@ +--- +title: "Understanding Slippage" +--- + +# Understanding Slippage + +## Introduction + +When staking and unstaking in Bittensor, *slippage* refers to a difference between the quantity of tokens actually received, and the amount that would be expected based on a static price. This difference is due to the change in price due to the transaction itself. + +Each Bittensor subnet operates as a *constant product AMM*, meaning that it will accept trades that conserve the product of the quantities of the two tokens in reserve, TAO and alpha. To calculate the price in one token of batch of the other token that a buyer wishes to acquire—alpha if they are staking, or TAO if they are unstaking—the algorithm assumes that the transaction does not change this product, so the product of TAO and alpha is the same before and after. + +
+ See how it's calculated! + + When staking, the product K of TAO in reserve and alpha in reserve is the same before and after the transaction, so the initial product must be equal to the product after the cost in TAO is added to the reserve, and the stake is removed from the reserve and placed in the staked hotkey. + + Before: + $$ + \tau_{\mathrm{in}} \,\alpha_{\mathrm{in}} = k + $$ + + After: + $$ + (\tau_{\mathrm{in}} + \text{cost}) \bigl(\alpha_{\mathrm{in}} - \text{stake}\bigr) = k + $$ + + Equal: + + $$ + (\tau_{\mathrm{in}} + \text{cost}) \bigl(\alpha_{\mathrm{in}} - \text{stake}\bigr) + = \tau_{\mathrm{in}} \,\alpha_{\mathrm{in}} + $$ + + + This means that if we choose to stake in a certain amount of TAO (if we specify the cost), then the yielded stake (the quantity of alpha to be removed from reserve and granted to the staked hotkey) is: + + $$ + \text{Stake} = \alpha_{\text{in}} - \frac{\tau_{\text{in}} \alpha_{\text{in}}} {\tau_{\text{in}} + \text{cost}} + $$ + + For example, suppose that a subnet has 100 alpha in reserve and 10 TAO, and we want to stake in 5 TAO. + + The price at this moment is 10 TAO / 100 alpha, or 10 alpha per TAO, so if we stake 5 TAO, we would expect 50 alpha, without taking slippage into account. + + With slippage, the actual alpha received will be less than 50 due to the price impact of the transaction. + + $$ + \text{Stake} = 100 - \frac{ 10 * 100} {10 + 5} + $$ + + or 33.333 alpha sent to the hotkey. So in this case, the slippage is the difference between the ideal expectation of 50 and the actual swap value of 33.33333: + + $$ + 16.667 = 50 - 33.333 + $$ + + This slippage is 50% of the actual swap value, which is extremely high, + because we chose small values for the available liquidity. In general, + slippage is high when available liquidity is limited compared to the + magnitude of the transaction, since the transaction itself is changing the + price significantly. + +
+ +## Calculating Slippage with the SDK + +You can use Bittensor's SDK to calculate expected slippage before executing transactions: + +### For Staking Operations + +```python +import bittensor as bt + +# Connect to network +subtensor = bt.Subtensor() +subnet_info = subtensor.subnet(netuid=1) + +# Calculate slippage for staking 10 TAO +amount_tao = 10.0 +slippage_percentage = subnet_info.tao_to_alpha_with_slippage(amount_tao, percentage=True) +print(f"Expected slippage for staking {amount_tao} TAO: {slippage_percentage:.2%}") + +# Get detailed breakdown +alpha_received, slippage_amount = subnet_info.tao_to_alpha_with_slippage(amount_tao) +ideal_alpha = subnet_info.tao_to_alpha(amount_tao) +print(f"Alpha received: {alpha_received}") +print(f"Slippage amount: {slippage_amount}") +print(f"Ideal (no slippage): {ideal_alpha}") +``` + +### For Unstaking Operations + +```python +# Calculate slippage for unstaking 100 alpha +amount_alpha = 100.0 +slippage_percentage = subnet_info.alpha_to_tao_with_slippage(amount_alpha, percentage=True) +print(f"Expected slippage for unstaking {amount_alpha} alpha: {slippage_percentage:.2%}") + +# Get detailed breakdown +tao_received, slippage_amount = subnet_info.alpha_to_tao_with_slippage(amount_alpha) +ideal_tao = subnet_info.alpha_to_tao(amount_alpha) +print(f"TAO received: {tao_received}") +print(f"Slippage amount: {slippage_amount}") +print(f"Ideal (no slippage): {ideal_tao}") +``` diff --git a/docs/learn/yc3-blog.md b/docs/learn/yc3-blog.md new file mode 100644 index 0000000000..ecf02e9e08 --- /dev/null +++ b/docs/learn/yc3-blog.md @@ -0,0 +1,150 @@ +--- +title: "How Yuma Consensus 3 Makes Bittensor More Fair" +--- + +# How Yuma Consensus 3 Makes Bittensor More Fair + +YC3 is the next evolution of Bittensor's consensus mechanism. It optimizes emissions to reward validators for recognizing innovation quickly. + +See also: +[Yuma Consensus](./yuma-consensus) +[Yuma Consensus 3 (YC3) Migration Guide](./yuma3-migration-guide) + +## Introduction: Understanding Yuma Consensus + +At the heart of every Bittensor subnet lies a fundamental challenge: how do you fairly distribute rewards for work, when that work can include a wide range of different digitial commodities or services? Bittensor approaches this as a distributed judgment problem: **Validators** serve as judges for the whole community, with trust in them being measured by the total stake they have been delegated. Their ratings of the performance of **miners** (who produce the commodities and services for each subnet) determine emissions to those miners. + +But how can we keep validators honest and hard-working to make sure that they do their best effort to accurately judge the miners? + +Yuma Consensus is Bittensor's solution. Validators continuously rank the quality of work done by miners in their subnet, with the rankings of validators being trusted in proportion to how much stake they have received from the community. Lazy or dishonest validators lose emissions for submitting inaccurate rankings, which is likely to cause the community to move their stake to more relabile validators. Hence the community's trust in a given validator, embodied as stake, is linked over time to the emissions earned by the miners that validator rates. Hence validators are kept honest and miners are kept working hard to produce the best commodities possible. + +But how does this work in detail? Each validator submits their rankings of miners they've evaluated. The algorithm then looks at all these rankings and tries to figure out which validators are giving the most reliable, honest evaluations. Validators who consistently make good predictions about which miners _other_ validators will _eventually_ recognize as the best, get _more_ influence in the system. Meanwhile, validators that give stale or otherwise inaccurate evaluations lose out. + +The system builds "bonds" between validators and miners over time. When a validator consistently recognizes a miner's good work, their bond with that miner strengthens, leading to better rewards for both parties. This creates a powerful incentive for validators to be diligent, honest, and forward-thinking in their evaluations. + +But the earlier versions of this system had some significant flaws—particularly when it came to rewarding validators who were ahead of the curve in recognizing promising miners, and ensuring fairness for validators with smaller stakes. Yuma Consensus 3 solves these problems. + +## The Evolution of Consensus + +The Yuma Consensus mechanism, which determines how emissions are distributed, has evolved through several iterations to address fairness concerns. + +### The Limitations of Earlier Versions + +#### Yuma Consensus V1 + +The first version of the algorithm distributed validator rewards based on stake and consensus weight, but had significant limitations: + +- Small validators faced unfair rounding issues +- Limited mechanisms for recognizing early adopters of promising miners + +#### Yuma Consensus V2 + +The second version introduced a more sophisticated bonding mechanism with exponential moving averages, but still struggled with: + +- Unfair penalties for small validators due to rounding errors +- Insufficient rewards for validators who recognized good miners early +- Uniform alpha parameters that didn't account for individual validator-miner relationships +- A serious bug in bond distribution, when validator participation changed dramatically. + +The last and most serious of these issues was that bonds were only redistributed when validators holding at least 50% of total stake cast votes for a given miner. This created a situation where: + +1. **Bonds would freeze** when validators stopped actively voting for a miner. +2. **Historical allocations persisted** for months, even when those validators were no longer evaluating the miner. +3. **New evaluators were locked out** until enough high-stake validators resumed voting. +4. **Unfair reward distribution** occurred when miners became relevant again - old bond holders received rewards despite not currently evaluating, while active evaluators received minimal bonds + +## Yuma Consensus V3 + +Yuma Consensus 3 addresses these fundamental issues with several breakthrough improvements: + +### Per-Bond EMA Scaling + +The most significant innovation in YC3 is that each validator-miner bond pair now gets its own adjustment rate (alpha value) rather than using a single rate for all bonds. This allows individual relationships to evolve at different speeds based on performance and consensus differences. + +When [Liquid Alpha is enabled](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L633-L640), the system calculates [individual alpha values](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1166-L1206) for each validator-miner pair using a [sigmoid function](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1274-L1302). When Liquid Alpha is disabled, it falls back to a [uniform alpha calculation](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1304-L1312) based on the bonds moving average parameter. + +### Fair Scaling for All Validators + +Bond values are computed using fixed-point arithmetic and then [converted to u16 for storage efficiency](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L859-L861), allowing precise fractional relationships while maintaining a 0-65535 storage scale. This fixes the disadvantages that plagued small-stake validators in previous versions. + +### Early Recognition Rewards + +Validators who identify promising miners before they become widely recognized can now start accumulating bonds early. This creates proper incentives for proactive evaluation rather than just following the crowd. + +The [alpha sigmoid function](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1274-L1302) calculates adjustment rates based on the difference between a validator's current weights and the network consensus. When a validator's weight for a miner differs significantly from consensus, the sigmoid determines whether to increase or decrease the bond adjustment rate, rewarding early recognition while preventing manipulation. + +## Understanding Bonds: The Key to Validator Rewards + +**Bonds** are the mechanism by which validators earn rewards for their evaluation work. Think of them as shares or stakes that validators accumulate with specific miners over time. + +Bonds held by a validator for a given miner, produce emissions in proportion to the strength of the bond and the emissions to the miner. See [source code.](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L712) + +**The Technical Implementation:** + +1. **Storage**: Bonds are stored as [sparse matrices](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L948-L964) on a 0-65535 scale for efficiency +2. **Computation**: Each epoch, bonds are updated via [Exponential Moving Average (EMA)](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L651-L658) based on validator weights and previous bond values +3. **Rewards**: Validator dividends are computed by multiplying bonds with miner incentives + +**Mathematical Foundation:** Under the hood, bonds follow the EMA equation. Here, $\Delta B_{ij}$ is the "instant bond" based on a validator's stake-weighted evaluation of a miner. + +$$ +B_{ij}^{(t)} = \alpha \,\Delta B_{ij} + (1-\alpha)\,B_{ij}^{(t-1)} +$$ + +However, YC3's innovation is that α can now be different for each validator-miner pair rather than uniform across all bonds. The system also applies a bonds penalty factor β when validator weights exceed consensus, helping maintain anti-fraud protection. For the complete mathematical treatment, see the main article on [Yuma Consensus](./yuma-consensus.md#bonding-mechanics). + +### How Validators Acquire Bonds + +**In Yuma v2** (the problematic version): A validator needed to vote on a miner while at least 50% of validators were also voting for that miner. This meant early discoverers got locked out until big validators joined. + +**In Yuma v3**: Validators can [build bonds independently](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1108-L1127) through the EMA process. When Liquid Alpha is enabled, each validator-miner pair gets its own alpha value, allowing bonds to accumulate even when others haven't recognized the miner yet. + +### Liquid Alpha Integration + +YC3 works seamlessly with Liquid Alpha, providing additional rewards for validators who vote for +miners that aren't yet receiving votes from others. This further encourages independent evaluation +and early recognition. +YC3 integrates with Liquid Alpha when [specific conditions are met](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L633-L640): + +1. Liquid Alpha must be enabled for the subnet +2. Consensus values must exist and contain non-zero values +3. The network must have sufficient activity + +When these conditions are satisfied, validators receive additional rewards for voting for miners that aren't yet receiving votes from others. If conditions aren't met, the system [falls back to traditional EMA bonding](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1108-L1115). + +### Enhanced EMA Smoothing + +The system maintains strong anti-fraud protection while providing smoother bond transitions. The adjustment rate is controlled by the [bonds moving average parameter](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1055-L1062), which can be configured up to 97.5% (meaning bonds change by 2.5% per epoch toward their target values). + +**Technical note:** The [EMA calculation](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1028) uses `alpha = 1 - (bonds_moving_average / 1_000_000)`, where bonds_moving_average is typically set to 975,000, resulting in approximately 2.5% adjustment per epoch. + +## The Real-World Impact + +YC3 creates a healthier ecosystem by encouraging validators to: + +- **Make independent evaluations** rather than copying popular validators +- **Recognize promising miners early** through differentiated bond adjustment rates +- **Maintain consistent evaluations** while being rewarded for good prediction accuracy +- **Participate meaningfully regardless of stake size** through fair scaling mechanisms + +This transformation means innovation and early recognition are properly rewarded, while maintaining the security and reliability that makes Bittensor networks trustworthy. + +## For Subnet Owners + +Yuma 3 works best in subnets where validators can independently evaluate miners and benefit from early recognition of promising innovations. The system distributes dividends more fairly than previous versions, and when combined with Liquid Alpha, provides powerful tools to encourage independent evaluation. + +YC3 can be [toggled per subnet](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L628) through governance mechanisms. The [alpha parameter controls](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L1316-L1356) allow fine-tuning of the sigmoid steepness and adjustment ranges for your specific subnet needs. + +**Important considerations:** + +- Liquid Alpha must be enabled to get full YC3 benefits +- The system requires active consensus formation to function optimally +- Bond reset functionality is available for subnets that need it + +## Looking Forward + +As Bittensor continues to grow, YC3 provides a solid foundation for fair and efficient consensus. The system's ability to reward early recognition while maintaining security makes it well-suited for the network's future development. + +For subnet owners ready to embrace more sophisticated consensus mechanisms, YC3 combined with Liquid Alpha provides a powerful toolkit for creating equitable and efficient subnet ecosystems. + +YC3 was introduced to the Subtensor Code base in [PR 1593](https://github.com/opentensor/subtensor/pull/1593). diff --git a/docs/yuma-consensus.md b/docs/learn/yuma-consensus.md similarity index 76% rename from docs/yuma-consensus.md rename to docs/learn/yuma-consensus.md index c5e57c42e8..20e002d74c 100644 --- a/docs/yuma-consensus.md +++ b/docs/learn/yuma-consensus.md @@ -6,28 +6,35 @@ title: "Yuma Consensus" ## Introduction -Yuma Consensus (YC) is a critical algorithmic process within Bittensor, which runs on-chain within Subtensor. Its responsibility is to compute validator and miner emissions from validators' rankings of miners. +Yuma Consensus (YC) is a critical algorithmic process within Bittensor, which runs on-chain within Subtensor. Its responsibility is to compute validator and miner emissions from validators' rankings of miners' performances. -Each of a subnet's validators periodically submit a vector of weights ranking the value of the work of each miner they've evaluated. The YC algorithm resolves this matrix of rankings into two **emissions vectors** that allocate emissions over participants based on their performance: one each for **miners** and **validators**. +Each of a subnet's validators periodically submits a vector of weights ranking the value of the work of each miner they've evaluated. The YC algorithm resolves this matrix of rankings into two **emissions vectors**—one each for **miners** and **validators**. These emissions vectors allocate emissions over participants based on their performances. The algorithm is designed to more heavily weight the inputs of more trusted validators, in order to ignore the portion of the validation signal that is less reliable. By disregarding unreliable weight-settings, YC incentivizes validators to be worthy of trust by working hard to give consistent, fast, honest evaluations of miners that predict the eventual convergence of other validators' evaluations. YC incentivizes miners to work hard for the highest combined evaluation by the community of validators. See: + +- [How Yuma Consensus 3 Makes Bittensor More Fair](./yc3-blog) +- [Yuma Consensus 3 Migration Guide](./yuma3-migration-guide.md) - [Emissions](./emissions) +- [Epoch Implementation](../navigating-subtensor/epoch.md) - Implementation details - [Subtensor Docs: Yuma Consensus](https://github.com/opentensor/subtensor/blob/main/docs/consensus.md) ## Clipping Clipping is designed to punish innacurate miner evaluation, especially in patterns that could constitute collusion to manipulate the accuracy of consensus to favor certain miners. -To achieve this, the judgment of the most trusted validators (as measured by stake) serves as a benchmark. Weights that exceed this benchmark are *clipped*, meaning neither the miner nor the validator receives emissions for them. +To achieve this, the judgment of the most trusted validators (as measured by stake) serves as a benchmark. Weights that exceed this benchmark are _clipped_, meaning neither the miner nor the validator receives emissions for them. This clipping protects against erroneous or collusive over-evaluation of miners by validators. +
+ See how it's calculated + To compute the benchmark $\overline{W_j}$ for miner $j$ and set $\mathbb{V}$ of the subnet's validators, we gather all validator weights $W_{ij}$ for any validator $i \in \mathbb{V}$, sort them by validator’s **stake** $S_i$, and then find the maximum weight level $w$ supported by at least a fraction $\kappa$ of total stake. $$ -\overline{W_j} = \arg \max_{w} +\overline{W_j} = \arg \max_{w} \Bigl(\, \sum_{i \in \mathbb{V}} S_i \,\cdot\, \bigl\{\,W_{ij}\,\ge w \bigr\} \ge \kappa \Bigr). @@ -42,14 +49,18 @@ $$ :::tip note Kappa is a configurable hyperparameter with default: $\kappa = 0.5$. -This means that if *least* generous half (0.5) of the validators (with each validator measured by stake, not 1 per validator) set weights for a given miner to no more than x, then the weights of the other, more generous, half of the validators for that miner are going to be clipped down to x. 'Generous' here refers to giving a high weight to the miner in question. +This means that if _least_ generous half (0.5) of the validators (with each validator measured by stake, not 1 per validator) set weights for a given miner to no more than x, then the weights of the other, more generous, half of the validators for that miner are going to be clipped down to x. 'Generous' here refers to giving a high weight to the miner in question. ::: +
+ ## Miner emissions Miner emissions are based on an aggregate ranking which is the summed rankings of validators, weighted by validators' stake, where $\overline{W_{ij}}$ is the post-clip weight. -$$ +
+ See how it's calculated + $$ R_j = \sum_{i \in \mathbb{V}} S_i \,\cdot\, \overline{W_{ij}} $$ @@ -59,25 +70,35 @@ $$ M_j = \frac{\,R_j\,}{\sum_{k \in \mathbb{M}} R_k} $$ +
+ ## Penalizing out-of-consensus bonds If a validator's evaluation of a miner is too high, it is penalized. If a submitted weight $W_{ij}$ by validator $i$ for miner $j$ exceeds the $j$'s consensus evaluation, $\overline{W_j}$, its bond value is penalized by factor $\beta$. +
+ See how it's calculated + Bond-weight $\widetilde{W_{ij}}$ is: $$ -\widetilde{W_{ij}} +\widetilde{W_{ij}} = (1-\beta)\,W_{ij} +\beta\,\overline{W_{ij}} $$ :::tip note -Penalty factor $\beta$ is a configurable hyperparameter. +Penalty factor $\beta$ is a configurable hyperparameter. ::: +
+ ## Bonding mechanics The **instant bond** $\Delta B_{ij}$ of validator $i$ to miner $j$ is equal to $i$’s stake, $\,S_i$ times $i$'s bond-weight for $j$ normalized by $j$'s total bond-weight for all $\mathbb{V}$ of the subnet's validators: +
+ See how it's calculated + $$ \Delta B_{ij} = \frac{\,S_i \,\cdot\, \widetilde{W_{ij}}\,}{ \sum_{k \in \mathbb{V}} S_k \,\cdot\, \widetilde{W_{kj}}} @@ -89,15 +110,22 @@ $$ B_{ij}^{(t)} = \alpha \,\Delta B_{ij} + (1-\alpha)\,B_{ij}^{(t-1)} $$ -Validators who stay near consensus build stronger EMA bonds and thus extract more emissions, while any attempt to overstate a particular miner’s performance is penalized. The EMA smooths out abrupt swings in validator behavior and incentivizes consistent alignment with the consensus. - :::tip note -The $\alpha$ variable here is unrelated to the concept of subnet specific currencies, referred to as alpha $\alpha$ tokens. Here $\alpha$ refers to a factor used in this EMA smoothing function—see [consensus-based weights, a.k.a. liquid alpha](./subnets/consensus-based-weights.md). +The $\alpha$ variable here is unrelated to the concept of subnet specific currencies, referred to as alpha $\alpha$ tokens. Here $\alpha$ refers to a factor used in this EMA smoothing function—see [consensus-based weights, a.k.a. liquid alpha](../concepts/consensus-based-weights.md). ::: +
+ +Validators who stay near consensus build stronger EMA bonds and thus extract more emissions, while any attempt to overstate a particular miner’s performance is penalized. The EMA smooths out abrupt swings in validator behavior and incentivizes consistent alignment with the consensus. + ## Validator emissions Each validator $i$’s share $V_i$ of validator emissions (41% of each subnet's total emissions) is the sum of all of its bonds to miners, weighted by the miner's total emissions: + +
+See how it's calculated $$ V_i = \sum_{j \in \mathbb{M}} \Bigl(\,B_{ij} \,\times\, M_j\Bigr) -$$ \ No newline at end of file +$$ + +
diff --git a/docs/learn/yuma3-migration-guide.md b/docs/learn/yuma3-migration-guide.md new file mode 100644 index 0000000000..d190d3100e --- /dev/null +++ b/docs/learn/yuma3-migration-guide.md @@ -0,0 +1,115 @@ +--- +title: "Yuma Consensus 3 (YC3) Migration Guide" +--- + +# Yuma Consensus 3 (YC3) Migration Guide + +Yuma Consensus 3 (YC3) is the latest version of the Yuma Consensus mechanism with significant improvements to validator fairness, bond mechanics, and precision handling. This guide will help subnet owners understand what's changed and how to migrate. + +See also: + +- [How Yuma Consensus 3 Makes Bittensor More Fair](./yc3-blog.md) - Technical deep dive and mathematical foundations +- [Subnet Hyperparameters](../subnets/subnet-hyperparameters.md) - Complete parameter reference +- [Yuma Consensus](./yuma-consensus.md) - Understanding the consensus mechanism +- [Subnet Creation](../subnets/create-a-subnet.md) - Creating new subnets with YC3 + +## What is YC3? + +YC3 is a drop-in replacement for the existing Yuma Consensus mechanism that addresses several critical issues while maintaining backward compatibility. Most subnet owners won't need to make any changes - the upgrade is designed to be seamless. + +The most significant innovation in YC3 is per-bond EMA scaling: each validator-miner bond pair now gets its own adjustment rate (alpha value) rather than using a single rate for all bonds. This allows individual relationships to evolve at different speeds based on performance and consensus differences. + +## Timeline + +- Current: YC3 is live and being adopted by subnets +- There is no forced migration deadline - subnets can adopt when ready + +## Key Improvements in YC3 + +### 1. Fair Validator Treatment + +- Problem Fixed: Small validators were previously penalized simply for being small due to rounding issues. +- YC3 Solution: Bond values are now computed using fixed-point arithmetic and converted to u16 for storage efficiency, allowing precise fractional relationships while maintaining a 0-65535 storage scale. + +### 2. Bond Precision Issues + +- Problem Fixed: 16-bit integer precision was insufficient for bond accumulation, causing some validators to receive no bonds despite giving weight to miners. +- YC3 Solution: Enhanced precision handling with fixed-point arithmetic ensures all validators receive appropriate bond allocations. + +### 3. Bond Upscaling and Decay + +- Problem Fixed: Bond upscaling when consensus equals zero was causing unfair distributions. +- YC3 Solution: Fixed bond mechanics with enhanced EMA smoothing ensure more predictable and fair reward distribution. + +### 4. Early Recognition Rewards + +- New Feature: Validators who identify promising miners before they become widely recognized can now start accumulating bonds early. +- Technical Implementation: The alpha sigmoid function calculates adjustment rates based on the difference between a validator's current weights and network consensus. + +### 5. Enhanced Tunability + +- New Feature: Additional parameters allow subnet owners to fine-tune their consensus mechanisms +- Backward Compatible: Existing subnets continue to work with default settings + +## Migration Process + +:::tip no-op +Validators and miners do not need to update their code. +::: + +### Subnet Creators + +Your subnet will continue to function as before until YC3 is enabled. + +To upgrade your subnet to YC3, use the coldkey with subnet creator permissions to run: + +``` +btcli sudo set --param yuma3_enabled +``` + +### Liquid Alpha Integration + +YC3 works with Liquid Alpha when specific conditions are met: + +1. Liquid Alpha must be enabled for the subnet +2. Consensus values must exist and contain non-zero values +3. The network must have sufficient activity + +When these conditions are satisfied, validators receive additional rewards for voting for miners that aren't yet receiving votes from others. + +```bash +# Enable Liquid Alpha +btcli sudo set --param liquid_alpha_enabled --value true --netuid YOUR_NETUID +``` + +## New Tunable Parameters + +YC3 introduces additional hyperparameters for advanced subnet customization: + +### Alpha Sigmoid Steepness + +Controls the steepness of the alpha sigmoid function, affecting reward distribution curves and how quickly bonds adjust to weight changes. + +```bash +# Set alpha sigmoid steepness +btcli sudo set --param alpha_sigmoid_steepness --value YOUR_VALUE --netuid YOUR_NETUID +``` + +### Bonds Moving Average + +The adjustment rate is controlled by the bonds moving average parameter, which can be configured up to 97.5% (meaning bonds change by 2.5% per epoch toward their target values). + +```bash +# Adjust bond smoothing (typical value: 975000 for 2.5% per epoch) +btcli sudo set --param bonds_moving_avg --value 975000 --netuid YOUR_NETUID +``` + +### Alpha High/Low Parameters + +Fine-tune the range of alpha values used in the sigmoid function: + +```bash +# Set alpha range parameters +btcli sudo set --param alpha_high --value YOUR_VALUE --netuid YOUR_NETUID +btcli sudo set --param alpha_low --value YOUR_VALUE --netuid YOUR_NETUID +``` diff --git a/docs/liquidity-positions/liquidity-positions.md b/docs/liquidity-positions/liquidity-positions.md new file mode 100644 index 0000000000..4193eeb4cd --- /dev/null +++ b/docs/liquidity-positions/liquidity-positions.md @@ -0,0 +1,138 @@ +--- +title: User Liquidity Positions (Uniswap) +--- + +# User Liquidity Positions (Uniswap) + +## Overview + +The Liquidity Position feature allows users to provide trading liquidity for specific subnets, within specified price ranges for the subnet $\alpha$ token. This system is based on Uniswap V3's concentrated liquidity model and enables providers to earn fees from trading activity. + +Any TAO holder can contribute to the health of a subnet by creating a Liquidity Position (LP), to provide liquidity for staking/unstaking and stabilizing the subnet's token price. Liquidity positions accumulate fees when users stake and unstake within the defined price range, which the creator of the LP can subsequently withdraw into their wallet. + +Subnet creators can enable/disable the liquidity positions feature on their subnets. + +:::tip +A LP does not accumulate fees for staking operations by the coldkey that owns it. +::: + +See also: + +- [Managing User Liquidity Positions Tutorial](./managing-liquidity-positions.md). + +### Liquidity Positions vs. Staking + +When you stake TAO to a validator, you're essentially voting for that validator's participation in the subnet's consensus mechanism. The validator's total stake (including your delegation) determines their share of emissions and influence in the network. + +Stakers earn emissions off of their stake, which are distributed each tempo. + +Liquidity Positions earn fees when others stake or unstake within the price range defined on the position. + +By providing liquidity to a subnet's trading pool, you're enabling other users to trade between TAO and the subnet's Alpha tokens, creating more liquid market conditions for the subnet and helping to stabilize the subnet's token price. + +### Dynamic token composition + +A liquidity position (LP) can hold TAO, alpha, or both. This depends on the subnet's current token price relative to the range specified for the LP when it was created. + +This compositions represents the token requirements for creating an LP depending, as well as token yield from removing liquidity form the position, depending on the token price relative to the LP's price window, at the block when the transaction executes. + +**Price below range** (`current_price < price_low`): + +- Position becomes **100% Alpha tokens** +- `amount_alpha = liquidity * (1/sqrt_price_low - 1/sqrt_price_high)` +- `amount_tao = 0` + +**Price within range** (`price_low <= current_price <= price_high`): + +- Position maintains **mixed token composition** +- `amount_alpha = liquidity * (1/sqrt_current_price - 1/sqrt_price_high)` +- `amount_tao = liquidity * (sqrt_current_price - sqrt_price_low)` + +**Price above range** (`current_price > price_high`): + +- Position becomes **100% TAO tokens** +- `amount_alpha = 0` +- `amount_tao = liquidity * (sqrt_price_high - sqrt_price_low)` + +[See source code](https://github.com/opentensor/bittensor/blob/master/bittensor/utils/liquidity.py#L28-L58) + +## Liquidity Position Lifecycle + +### Creating Positions + +To create an LP, the user specifies a _liquidity_ parameter, which is converted into some combination of TAO and alpha token balances. TAO are taken from the users coldkey, alpha tokens are taken from the hotkey on which the Liquidity Position was created, and they are locked up in the LP. + +### Modifying a Position + +Its creator can modify an existing LP by adding or removing liquidity. The same formula is applied to determine the required tokens when adding liquidity, and to determine the yield of tokens when exiting liquidity, as when creating the LP. + +### Fee Accumulation + +Fees are generated when users perform swaps (trading TAO for Alpha or vice versa) within their position's price range. + +:::tip +Fees are not added to your position's liquidity, they are tracked separately, in the position's `fees_tao` and `fees_alpha` fields. + +See: [Managing User Liquidity Positions Tutorial: View your LPs](./managing-liquidity-positions.md#view-your-lps) +::: + + + +The blockchain calculates fees for each position based on: + +- Quantity staked/unstaked, tao/alpha respectively +- The the position's liquidity relative to other LPs that have their price range include the transaction. + +[See source code](https://github.com/opentensor/subtensor/blob/master/pallets/swap/src/position.rs#L110-L128) + +#### Fee Distribution + +Fees are not distributed automatically per tempo like emissions. Instead, fees are only distributed to your wallet when you actively withdraw liquidity: + +- **When modifying a position** (adding or removing liquidity): All accumulated fees are automatically collected and sent to your wallet. + [See source code](https://github.com/opentensor/subtensor/blob/master/pallets/swap/src/pallet/mod.rs#L410-L415) + +- **When removing a position entirely**: All accumulated fees are collected along with your position's tokens. + [See source code](https://github.com/opentensor/subtensor/blob/master/pallets/swap/src/pallet/mod.rs#L520-L535) + +This means you must actively manage your positions to claim your earned fees - they remain locked in the position until you perform a position operation (modify or remove). + +### Removing a Position + +When a position is destroyed/removed, the position's liquidity is converted back to tokens based on the current subnet price relative to your position's price range. The position is then deleted from the system. + +[See source code](https://github.com/opentensor/bittensor/blob/master/bittensor/core/extrinsics/asyncex/liquidity.py#L127-L185) + +## The `liquidity` Parameter + +The `liquidity` parameter that defines a LP is **not** an amount of TAO or Alpha tokens (or even a sum of the two). Instead, it's a mathematical scaling factor from Uniswap V3's concentrated liquidity model, which calculates the token amounts deducted from your hotkey and coldkey (alpha and TAO respectively) when creating a LP. + +The actual TAO and Alpha amounts that get locked are calculated by the `to_token_amounts()` function, represented below in pseudocode. + +:::note +The composition of the tokens required to create an LP depends on the current token price. +::: + +```python +if current_price < price_low { + # Only Alpha tokens required + alpha_amount = liquidity * (1/√price_low - 1/√price_high) + tao_amount = 0 +} else if current_price > price_high { + # Only TAO tokens required + tao_amount = liquidity * (√price_high - √price_low) + alpha_amount = 0 +} else { + # Both TAO and Alpha required + tao_amount = liquidity * (√current_price - √price_low) + alpha_amount = liquidity * (1/√current_price - 1/√price_high) +} +``` + +See also: + +- [See source code](https://github.com/opentensor/subtensor/blob/master/pallets/swap/src/position.rs#L80-L122) diff --git a/docs/liquidity-positions/managing-liquidity-positions.md b/docs/liquidity-positions/managing-liquidity-positions.md new file mode 100644 index 0000000000..acbdbf912b --- /dev/null +++ b/docs/liquidity-positions/managing-liquidity-positions.md @@ -0,0 +1,615 @@ +--- +title: Managing User Liquidity Positions Tutorial +--- + +In this tutorial we will explore the behavior of Bittensor's Uniswap-style user liquidity positions (LPs). To facilitate this, we'll deploy a Subtensor blockchain locally and create a subnet on it. + +Liquidity positions can be complicated and potentially confusing, as their behavior is sensitive to the subnet price relative to the position's high' and 'low' price boundaries, at several stages of their life-cycle: + +- When a LP is created +- When liquidity is added to an existing LP by modifying it +- During fee accrual +- When liquidity is exited from an existing LP by modifying it +- When liquidity is exited from an existing LP by removing (deleting) the position. + +## Setup + +### Deploy a Bittensor (Subtensor) blockchain locally. + +See: [Deploy a Local Bittensor Blockchain Instance](../local-build/deploy) + +Or try the easy way, by running: + +```bash +docker run --rm --name test_local_chain_ -p 9944:9944 -p 9945:9945 ghcr.io/opentensor/subtensor-localnet:devnet-ready +``` + +### Create a subnet + +Create a subnet managed by the Alice wallet. + +See [Provision wallets: Access the Alice account](../local-build/provision-wallets#access-the-alice-account) + +``` +btcli subnet create \ +--subnet-name awesome-first-subnet \ +--wallet.name alice \ +--network ws://127.0.0.1:9945 +``` + + + +### Start emissions + +First, use the subnet creator key to start emissions on the subnet. Assuming your want to use subnet 2, run: + +```shell +btcli subnet start --netuid 2 \ +--wallet.name sn-creator \ +--network ws://127.0.0.1:9945 +``` + +```console +Are you sure you want to start subnet 2's emission schedule? [y/n]: y +Enter your password: +Decrypting... +✅ Successfully started subnet 2's emission schedule. +``` + +:::tip +After some time has passed, you'll be able to confirm that emissions are flowing by inspecting your subnet's token economy. You'll see a non-zero amount in the _Emissions_ column, indicating, even if no mining activity is occuring, the subnet creator key accumulates emissions. + +If you have only started one subnet, you'll see that it's emissions are always exactly 1 $\tau$. + +See [Emissions](../learn/emissions) + +```shell + btcli view dashboard \ +--wallet.name sn-creator \ +--network ws://127.0.0.1:9945 +``` + +::: + +### Configure the `user_liquidity_enabled` hyperparameter + +Set the `user_liquidity_enabled` hyperparameter to `True` from its default value of `False`. + +```shell +btcli sudo set --netuid 2 \ +--parameter user_liquidity_enabled \ +--value True \ +--wallet.name sn-creator \ +--network ws://127.0.0.1:9945 + +``` + +```console +✅ Hyperparameter user_liquidity_enabled changed to True + + Subnet Hyperparameters + NETUID: 2 (awesome-first-subnet) - Network: custom + + HYPERPARAMETER VALUE NORMALIZED + ──────────────────────────────────────────────────────────────────────── + + (all the hyperparameters...) + + user_liquidity_enabled True True + ──────────────────────────────────────────────────────────────────────── +``` + +:::tip +Confirm the subnet configuration with the following command, checking that `user_liquidity_enabled` is `True`. + +``` +btcli subnet hyperparameters --netuid 2 --network ws://127.0.0.1:9945 +``` + +::: + +### Create and fund a liquidity manager wallet + +Additionally, in order to manage liquidity on a subnet, a user use a hotkey that has some stake on the subnet. Therefore you must register and stake some liquidity into the hotkey. This alpha liquidity will be used for the alpha component when you add liquidity to a position, when creating or modifying it. + +1. Create the wallet + ```shell + btcli w create --wallet.name liquidity-manager --hotkey lp-hotkey + ``` +2. Transfer funds from the Alice account + ``` + btcli wallet transfer \ + --amount 1001 \ + --wallet.name alice \ + --destination "5F7LNFEmsngMV2yaA41WPeYuQmVGcesu5TPJizPDpSUHviVr" \ # Coldkey public key for your liquidity-manager wallet + --network ws://127.0.0.1:9945 + ``` +3. Check your balance in the dashboard + + ```shell + btcli view dashboard \ + --wallet.name liquidity-manager \ + --network ws://127.0.0.1:9945 + ``` + +4. Register your liquidity-manager's hotkey. + + This is the hotkey that will contain alpha stake related to the position. When you add alpha liquidity to the position, it will come from this hotkey, and when you exit it from the position, it will be credited to this hotkey. + + You can either use your wallet's name for the hotkey (as below), or specify the hotkey's ss58 address in interactive mode. If you need to find your hotkey's ss58, use `btcli wallet list`. + + :::tip + On a local blockchain running in fastblocks mode, you will likely need to use the `--period` flag to give you a long enough window before your registration request will expire. + ::: + + ```shell + btcli subnet register \ + --wallet.name liquidity-manager \ + --wallet.hotkey hotsauce \ + --period 20 \ + --network ws://127.0.0.1:9945 + ``` + + ```console + Register to netuid: 2 + Network: custom + + Netuid ┃ Symbol ┃ Cost (Τ) ┃ Hotkey ┃ Coldkey + ━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + 2 │ β │ τ 0.0913 │ 5DJepbhrkAVdf5L3kXLMvjHu8TBB62AAGN8U4LjTtQYoKG9R │ 5F7LNFEmsngMV2yaA41WPeYuQmVGcesu5TPJizPDpSUHviVr + ────────┼────────┼──────────┼──────────────────────────────────────────────────┼────────────────────────────────────────────────── + │ │ │ │ + Your balance is: 1,001.0000 τ + The cost to register by recycle is 0.0913 τ + Do you want to continue? [y/n] (n): y + Enter your password: + Decrypting... + Balance: + 1,001.0000 τ ➡ 1,000.9087 τ + ✅ Registered on netuid 2 with UID 1 + ``` + +## Creating liquidity positions + +The token input when creating a LP depends on whether the current token price is above, below, or within the window between the high and low price that define the position. Therefore you should always check the current token price when creating, removing, or modifying positions, so you correctly anticipate the behavior. + +To observe the token input behavior of liquidity positions, let's create attempt to create 3 LPs, such that the current price is below, within, and above, the positions' respective price windows. + +If we attempt to create an LP with high window, i.e. with its low price above the current token price, or if we attempt to create one with a window that spans the current price, it will fail. That is because the token composition for a LP with a high window is entirely alpha, and for a LP with a window that spans the current price, it is mixed TAO and alpha. Therefore, to create the LP requires some alpha to be staked into the hotkey, and currently the hotkey has no stake. + +However, if we attempt to create a LP with a low window relative to the current price, i.e. with its high price below the current price, it will succeed, because the LP is composed entirely of TAO. + +See [Liquidity Positions: Dynamic token composition](./#dynamic-token-composition). + +### Check the price + +Always check the token price prior to creating LPs so you can predict their behavior. + +To easily view token prices on your local chain, as well as your TAO balance and alpha stakes, use the BTCLI dashboard: + +``` +btcli view dashboard \ +--wallet.name liquidity-manager \ +--network ws://127.0.0.1:9945 +``` + +You can also check the price with the following: + +``` +btcli subnet list --network ws://127.0.0.1:9945 + + Subnets + Network: custom + + + ┃ ┃ Price ┃ Market Cap ┃ ┃ ┃ ┃ ┃ + Netuid ┃ Name ┃ (Τ_in/α_in) ┃ (α * Price) ┃ Emission (Τ) ┃ P (Τ_in, α_in) ┃ Stake (α_out) ┃ Supply (α) ┃ Tempo (k/n) +━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━ + 0 │ τ root │ 1.0000 τ/Τ │ τ 0.00 │ τ 0.0000 │ -, - │ Τ 0.00 │ 0.00 Τ /21M │ -/- + 2 │ β awesome-first-subnet │ 1.0001 τ/β │ τ 13.02k │ τ 1.0000 │ τ 7.00k, 7.00k β │ 6.02k β │ 13.02k β /21M │ 3/10 + 1 │ α apex │ 0.0000 τ/α │ τ 0.00 │ τ 0.0000 │ τ 10.00, 10.00 α │ 1.00 α │ 11.00 α /21M │ 21/100 +────────┼────────────────────────┼─────────────┼─────────────┼──────────────┼─────────────────────────┼───────────────┼───────────────┼───────────── +``` + +### High and spanning window + +These requests are bound to fail, because we have not yet staked any alpha to the hotkey: + +``` +btcli liquidity add --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager --hotkey hotsauce + +Enter the amount of liquidity: 10 +Enter liquidity position low price: 1.1 +Enter liquidity position high price (must be greater than low price): 1.3 + +You are about to add a LiquidityPosition with: + liquidity: 10.0000 τ + price low: 1.1000 τ + price high: 1.3000 τ + to SN: 2 + using wallet with name: liquidity-manager +Would you like to continue? [y/n]: y +Error: Subtensor returned `InsufficientBalance(Module)` error. This means: `The caller does not have enough balance for the operation. + +btcli liquidity add --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager --hotkey hotsauce --liquidity 10 --price-low .5 --price-high 1.5 + +You are about to add a LiquidityPosition with: + liquidity: 10.0000 τ + price low: 0.5000 τ + price high: 1.5000 τ + to SN: 2 + using wallet with name: liquidity-manager +Would you like to continue? [y/n]: y +Error: Subtensor returned `InsufficientBalance(Module)` error. This means: `The caller does not have enough balance for the operation. +``` + +### If the current price is below the window + +However, the following position can be created, because its high price is below the current token price. + +```shell +btcli liquidity add --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager +``` + +```console +Enter the amount of liquidity: 10 +Enter liquidity position low price: .5 +Enter liquidity position high price (must be greater than low price): .7 +Enter your password: +Decrypting... +You are about to add a LiquidityPosition with: + liquidity: 100.0000 τ + price low: 0.5000 τ + price high: 0.7000 τ + to SN: 2 + using wallet with name: liquidity-manager +Would you like to continue? [y/n]: y +LiquidityPosition has been successfully added. +``` + +View the position by running: + +```shell +btcli liquidity list --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager +``` + +```console + + Liquidity Positions of liquidity-manager wallet in SN #2 + Alpha and Tao columns are respective portions of liquidity. +┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┓ +┃ ID ┃ Liquidity ┃ Alpha ┃ Tao ┃ Price low ┃ Price high ┃ Fee TAO ┃ Fee Alpha ┃ +┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━┩ +│ 2 │ 10.0 │ 0.0000 β │ 1.2956 τ │ 0.5000 τ │ 0.7001 τ │ 0.0000 τ │ 0.0000 β │ +└────┴───────────┴──────────┴──────────┴───────────┴────────────┴──────────┴───────────┘ + +``` + +### Add alpha to the liquidity manager hotkey + +Next, stake into your hotkey so you'll be able to create those other LPs. + +:::note notes +Use `--partial` to make things easier; this option allows you to specify a large staking amount, and an amount will be staked up to your tolerance threshold. + +If you don't use partial (or unsafe-staking mode), you'll have to find a staking amount that will be tolerated by your slippage limit. +::: + +```shell +btcli stake add --netuid 2 \ +--hotkey hotsauce --amount 10 \ +--wallet.name liquidity-manager \ +--partial \ +--network ws://127.0.0.1:9945 +``` + +```console +Safe staking: enabled (from config). +Rate tolerance: 0.005 (0.5%) by default. Set this using `btcli config set` or `--tolerance` flag +Partial staking: enabled. + + + Wallet Coldkey Balance + Network: custom + + Wallet Name Coldkey Address Free Balance Staked Value Total Balance + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + liquidity-manager 5F7LNFEmsngMV2yaA41WPeYuQmVGcesu5TPJizPDpSUHviVr 1,000.9100 τ 0.0000 τ 1,000.9100 τ + + + + Total Balance 1,000.9100 τ 0.0000 τ 1,000.9100 τ + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Amount to stake (TAO τ): 10 + + Staking to: + Wallet: liquidity-manager, Coldkey ss58: 5F7LNFEmsngMV2yaA41WPeYuQmVGcesu5TPJizPDpSUHviVr + Network: custom + + Netuid ┃ Hotkey ┃ Amount (Τ) ┃ Rate (per Τ) ┃ Received ┃ Fee (τ) ┃ Rate with tolerance: (0.5%) ┃ Partial stake enabled +━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━ + 2 │ 5DJepbhrkAVdf5L3kXLMvjHu8TBB62AAGN8U4LjTtQYoKG9R │ 10.0000 τ │ 0.666633241675929 β/Τ │ 6.6663 β │ Τ 0.0299 │ 0.6633 β/Τ │ True +────────┼──────────────────────────────────────────────────┼────────────┼────────────────────────┼──────────┼──────────┼─────────────────────────────┼─────────────────────── + │ │ │ │ │ │ │ + +Description: +The table displays information about the stake operation you are about to perform. +The columns are as follows: + - Netuid: The netuid of the subnet you are staking to. + - Hotkey: The ss58 address of the hotkey you are staking to. + - Amount: The TAO you are staking into this subnet onto this hotkey. + - Rate: The rate of exchange between your TAO and the subnet's stake. + - Received: The amount of stake you will receive on this subnet after slippage. + - Rate Tolerance: Maximum acceptable alpha rate. If the rate exceeds this tolerance, the transaction will be limited or rejected. + - Partial staking: If True, allows staking up to the rate tolerance limit. If False, the entire transaction will fail if rate tolerance is exceeded. + +Would you like to continue? [y/n]: y +Enter your password: +Decrypting... +✅ Finalized. Stake added to netuid: 2 +Balance: + 1,000.9100 τ ➡ 990.9100 τ +Subnet: 2 Stake: + 0.0000 τ ➡ 6.6299 β +``` + +If you now view your dashboard, you'll see that your TAO balance has reduced by the staked amount, plus the amount of $\tau$ locked into the liquidity position. + +``` + btcli view dashboard \ +--wallet.name liquidity-manager \ +--network ws://127.0.0.1:9945 +``` + +Now let's try again to create the positions that previously we could not. + +#### High window position + +```shell + +btcli liquidity add --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager --hotkey hotsauce --liquidity 10 --price-low 1.1 --price-high 1.3 +``` + +#### Spanning window position + +```shell +btcli liquidity add --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager --hotkey hotsauce --liquidity 10 --price-low .5 --price-high 1.5 +``` + +### View your LPs + +Now we can see all LPs listed. + +:::note +The `liquidity` parameter you specify is **not** the amount of TAO/Alpha tokens that will be locked up. Instead, it's a mathematical scaling factor from Uniswap V3's concentrated liquidity model, which calculates the token amounts deducted from your hotkey and coldkey (alpha and TAO respectively) when creating a LP. + +Hence you are not charged 10 TAO to create a LP with a magnitude of 10, in this case note that the quantity is 1.295 +::: + +```shell +btcli liquidity list --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager + + Liquidity Positions of liquidity-manager wallet in SN #2 + Alpha and Tao columns are respective portions of liquidity. +┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┓ +┃ ID ┃ Liquidity ┃ Alpha ┃ Tao ┃ Price low ┃ Price high ┃ Fee TAO ┃ Fee Alpha ┃ +┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━┩ +│ 5 │ 10.0 │ 1.8226 β │ 2.9407 τ │ 0.5000 τ │ 1.4999 τ │ 0.0000 τ │ 0.0000 β │ +│ 4 │ 10.0 │ 0.7638 β │ 0.0000 τ │ 1.1000 τ │ 1.2999 τ │ 0.0000 τ │ 0.0000 β │ +│ 2 │ 10.0 │ 0.0000 β │ 1.2956 τ │ 0.5000 τ │ 0.7001 τ │ 0.0000 τ │ 0.0000 β │ +└────┴───────────┴──────────┴──────────┴───────────┴────────────┴──────────┴───────────┘ +``` + +## + +Now let's see what happens when we stake and unstake within the trading window of liquidity positions. + +Create a validator coldkey if you don't have one, (See [Provision Wallets for Local Deploy](../local-build/provision-wallets) and [Mine and Validate (Locally): Register](../local-build/mine-validate)) then transfer a small amount of TAO to it from the Alice wallet. + +Then register a hotkey for it on subnet 2. + +Now, let's stake to it from the Alice wallet. + +``` +btcli stake add --netuid 2 \ +--network ws://127.0.0.1:9945 --wallet.name alice --partial --amount 1000 + +Safe staking: enabled (from config). +Rate tolerance: 0.005 (0.5%) by default. Set this using `btcli config set` or `--tolerance` flag +Partial staking: enabled. + + +Enter the wallet hotkey name or ss58 address to stake to (or Press Enter to view delegates): +Using the wallet path from config: /Users/michaeltrestman/.bittensor/wallets + + + + Subnet 2: awesome-first-subnet + Network: custom + + UID ┃ Stake (β) ┃ Alpha (β) ┃ Tao (τ) ┃ Dividends ┃ Incentive ┃ Emissions (β) ┃ Hotkey ┃ Coldkey ┃ Identity +━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━ + 0 │ 11.35k β │ 11.35k β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5Grwva │ 5Grwva │ (*Owner controlled) + 2 │ 751.95 β │ 751.95 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 9.020050 β │ 5CffqS │ 5EEy34 │ ~ + 1 │ 10.84 β │ 10.84 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5DJepb │ 5F7LNF │ ~ +─────┼───────────┼───────────┼─────────┼───────────┼───────────┼───────────────┼────────┼─────────┼───────────────────── + │ 12.12k β │ 12.12k β │ 0.00 β │ 0.000 │ │ 9.0201 β │ │ │ + + + +Enter the UID of the delegate you want to stake to (or press Enter to cancel): 2 + +Selected delegate: 5CffqSVhydFJHBSbbgfVLAVkoNBTsv3wLj2Tsh1cr2kfanU6 + + Staking to: + Wallet: alice, Coldkey ss58: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + Network: custom + + Netuid ┃ Hotkey ┃ Amount (Τ) ┃ Rate (per Τ) ┃ Received ┃ Fee (τ) ┃ Rate with tolerance: (0.5%) ┃ Partial stake enabled +━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━ + 2 │ 5CffqSVhydFJHBSbbgfVLAVkoNBTsv3wLj2Tsh1cr2kfanU6 │ 1,000.0000 τ │ 0.9926136629572226 β/Τ │ 992.6137 β │ Τ 2.9908 │ 0.9877 β/Τ │ True +────────┼──────────────────────────────────────────────────┼──────────────┼─────────────────────────┼────────────┼──────────┼─────────────────────────────┼─────────────────────── + │ │ │ │ │ │ │ + +Description: +The table displays information about the stake operation you are about to perform. +The columns are as follows: + - Netuid: The netuid of the subnet you are staking to. + - Hotkey: The ss58 address of the hotkey you are staking to. + - Amount: The TAO you are staking into this subnet onto this hotkey. + - Rate: The rate of exchange between your TAO and the subnet's stake. + - Received: The amount of stake you will receive on this subnet after slippage. + - Rate Tolerance: Maximum acceptable alpha rate. If the rate exceeds this tolerance, the transaction will be limited or rejected. + - Partial staking: If True, allows staking up to the rate tolerance limit. If False, the entire transaction will fail if rate tolerance is exceeded. + +Would you like to continue? [y/n]: y +✅ Finalized. Stake added to netuid: 2 +Balance: + 996,967.4407 τ ➡ 996,934.4742 τ +Partial stake transaction. Staked: + 32.9665 τ instead of 1,000.0000 τ +Subnet: 2 Stake: + 420.9182 β ➡ 457.4970 β +``` + +So now, examining the liquidity positions, we can see that some small amount of fees have accumulated to the LP whose window spans the current price, but not the others. + +Note that the fees have accumulated to `Fee TAO`, but not to `Fee Alpha`. + +```shell + btcli liquidity list --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager + + Liquidity Positions of liquidity-manager wallet in SN #2 + Alpha and Tao columns are respective portions of liquidity. +┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┓ +┃ ID ┃ Liquidity ┃ Alpha ┃ Tao ┃ Price low ┃ Price high ┃ Fee TAO ┃ Fee Alpha ┃ +┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━┩ +│ 4 │ 10.0 │ 1.7729 β │ 2.9908 τ │ 0.5000 τ │ 1.4999 τ │ 0.0001 τ │ 0.0000 β │ +│ 3 │ 10.0 │ 0.7638 β │ 0.0000 τ │ 1.1000 τ │ 1.2999 τ │ 0.0000 τ │ 0.0000 β │ +│ 2 │ 10.0 │ 0.0000 β │ 1.2956 τ │ 0.5000 τ │ 0.7001 τ │ 0.0000 τ │ 0.0000 β │ +└────┴───────────┴──────────┴──────────┴───────────┴────────────┴──────────┴───────────┘ +``` + +Now let's unstake and see what happens + +```shell +btcli stake remove --netuid 2 \ +--partial \ +--wallet.name alice \ +--network ws://127.0.0.1:9945 +``` + +```console +Safe staking: enabled (from config). +Rate tolerance: 0.005 (0.5%) by default. Set this using `btcli config set` or `--tolerance` flag +Partial staking: enabled. + +Enter the hotkey name or ss58 address to unstake from (or Press Enter to view existing staked hotkeys): + + Hotkeys with Stakes for Subnet 2 + + Index ┃ Identity ┃ Netuids ┃ Hotkey Address +━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + 0 │ 5Grw...utQY │ 2 │ 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + 1 │ 5Cff...anU6 │ 2 │ 5CffqSVhydFJHBSbbgfVLAVkoNBTsv3wLj2Tsh1cr2kfanU6 +───────┼─────────────┼─────────┼────────────────────────────────────────────────── + │ │ │ + +Enter the index of the hotkey you want to unstake from [0/1]: 1 + + + + Stakes for hotkey + 5Cff...anU6 +5CffqSVhydFJHBSbbgfVLAVkoNBTsv3wLj2Tsh1cr2kfanU + 6 + + Subnet ┃ Symbol ┃ Stake Amount ┃ Rate (Τ/α) +━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━ + 2 │ β │ 3,067.5744 β │ 1.012479 τ/β +────────┼────────┼──────────────┼────────────── + │ │ │ + + +Unstake all: 3,067.5744 β from 5Cff...anU6 on netuid: 2? [y/n/q] (n): y + + Unstaking to: + Wallet: alice, Coldkey ss58: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + Network: custom + + Netuid ┃ Hotkey ┃ Amount (α) ┃ Rate (Τ/α) ┃ Fee (α) ┃ Received (Τ) ┃ Rate with tolerance: (0.5%) ┃ Partial unstake enabled +━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━ + 2 │ 5Cff...anU6 │ 3,067.5744 β │ 1.012479(Τ/β) │ 9.1744 β │ 3,105.8531 τ │ 1.007416 Τ/β │ True +────────┼─────────────┼──────────────┼───────────────┼──────────┼──────────────┼─────────────────────────────┼───────────────────────── + │ │ │ │ │ 3,105.8531 τ │ │ + +Description: +The table displays information about the stake remove operation you are about to perform. +The columns are as follows: + - Netuid: The netuid of the subnet you are unstaking from. + - Hotkey: The ss58 address or identity of the hotkey you are unstaking from. + - Amount to Unstake: The stake amount you are removing from this key. + - Rate: The rate of exchange between TAO and the subnet's stake. + - Fee: The transaction fee for this unstake operation. + - Received: The amount of free balance TAO you will receive on this subnet after slippage and fees. + - Slippage: The slippage percentage of the unstake operation. (0% if the subnet is not dynamic i.e. root). + - Rate Tolerance: Maximum acceptable alpha rate. If the rate reduces below this tolerance, the transaction will be limited or rejected. + - Partial unstaking: If True, allows unstaking up to the rate tolerance limit. If False, the entire transaction will fail if rate tolerance is exceeded. + +Would you like to continue? [y/n]: y +✅ Finalized +Balance: + 996,934.4742 τ ➡ 997,054.1796 τ +Partial unstake transaction. Unstaked: + 118.8823 β instead of 3,067.5744 β +Subnet: 2 Stake: + 3,075.3541 β ➡ 2,956.4718 β +Unstaking operations completed. +``` + +Now, viewing our LP again, we can see that fees have accumulated to the position's `Fee Alpha` attribute. + +```shell +btcli liquidity list --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager + + Liquidity Positions of liquidity-manager wallet in SN #2 + Alpha and Tao columns are respective portions of liquidity. +┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┓ +┃ ID ┃ Liquidity ┃ Alpha ┃ Tao ┃ Price low ┃ Price high ┃ Fee TAO ┃ Fee Alpha ┃ +┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━┩ +│ 4 │ 10.0 │ 1.7978 β │ 2.9657 τ │ 0.5000 τ │ 1.4999 τ │ 0.0001 τ │ 0.0001 β │ +│ 3 │ 10.0 │ 0.7638 β │ 0.0000 τ │ 1.1000 τ │ 1.2999 τ │ 0.0000 τ │ 0.0000 β │ +│ 2 │ 10.0 │ 0.0000 β │ 1.2956 τ │ 0.5000 τ │ 0.7001 τ │ 0.0000 τ │ 0.0000 β │ +└────┴───────────┴──────────┴──────────┴───────────┴────────────┴──────────┴───────────┘ +``` + +## Remove liquidity from the position + +Let's remove the LP and recover the liquidity inside. To see how this affects our balance, run the `dashboard` command once before the `liquidity remove` command, and once after. You will see a small increase in your token balances. + +:::tip +You can find the required LP ID with `btcli liquidity list`, as seen above. +::: + +```shell +btcli liquidity remove --netuid 2 --network ws://127.0.0.1:9945 --wallet.name liquidity-manager +``` + +```console +Enter the liquidity position ID: 5 +Enter the SS58 of the hotkey to use for this transaction.: 5DJepbhrkAVdf5L3kXLMvjHu8TBB62AAGN8U4LjTtQYoKG9R + +You are about to remove LiquidityPositions with: + Subnet: 2 + Wallet name: liquidity-manager + Position id: 5 +Would you like to continue? [y/n]: y +Enter your password: +Decrypting... +Position 5 has been removed. +``` diff --git a/docs/local-build/create-subnet.md b/docs/local-build/create-subnet.md index f6ed712a54..921f2b3306 100644 --- a/docs/local-build/create-subnet.md +++ b/docs/local-build/create-subnet.md @@ -8,151 +8,87 @@ This page covers creating a subnet on a locally deployed Subtensor blockchain, w For creating a subnet on Bittensor test and main network, see [Create a Subnet](../subnets/create-a-subnet). -Prerequisites: -- [Deploy a Subtensor chain locally](./deploy) -- [Provision wallets for the sn-creator, miner, and validator users for this tutorial.](./provision-wallets) +## Prerequisites + +Before continuing with the rest of this tutorial, make sure you've completed the following: +- [Deploy a Subtensor chain locally](./deploy) +- [Provision wallets for the subnet creator, miner, and validator users for this tutorial.](./provision-wallets) +- Sufficient amount of TAO in your subnet creator wallet to cover the [burn cost](../resources/glossary.md#burn-cost). -## Create subnet +## Create a subnet -To access the handy pre-provisioned development "Alice" account on your local chain, use: +Now, let us create a new subnet on the local chain. To create a new subnet, run the following command in your terminal: ```shell btcli subnet create \ --subnet-name awesome-first-subnet \ --wallet.name sn-creator \ ---subtensor.chain_endpoint ws://127.0.0.1:9945 +--network ws://127.0.0.1:9945 ``` -### Trouble shoot -#### Insufficient funds -If you are following this tutorial for the first time, the `subnet create` command will faill with an insufficient balance error. - -The coldkey signing the `subnet create` transaction must have a sufficient $\tau$ balance to cover the burn cost of subnet creation, so called because the funds cannot be recovered. +You will then be prompted to provide the wallet hotkey as well as configure the subnet as shown: ```console Subnet burn cost: τ 1,000.0000 -Your balance of: τ 0.0000 is not enough to burn τ 1,000.0000 to register a subnet. +Your balance is: τ 1,001.0000 +Do you want to burn τ 1,000.0000 to register a subnet? [y/n]:y +Enter your password: +Decrypting... +🌏 📡 Registering subnet.. ``` -Transfer funds from the Alice account to cover it and try again. Consult `btcli w list` and carefully check the ss58 address of the destination coldkey (in this case, the one with the name `sn-creator`). +To check on your newly created subnets, run the following command in your terminal: ```shell -btcli wallet transfer \ ---amount 1001 \ ---wallet.name alice \ ---destination "5C9xw4..." \ ---subtensor.chain_endpoint ws://127.0.0.1:9945 +btcli subnet list --network ws://127.0.0.1:9945 ``` +A list of all subnets in your local subtensor instance is returned: -#### Network Rate Limit Error - -If you see a network rate limit error, you may need to adjust the `SubtensorInitialNetworkRateLimit` chain state parameter. - -See [Clone and tweak the Subtensor source](./deploy#clone-and-tweak-the-subtensor-source) +```console + Subnets + Network: custom + ┃ ┃ Price ┃ Market Cap ┃ ┃ P (τ_in, ┃ Stake ┃ ┃ + Netuid ┃ Name ┃ (τ_in/α_in) ┃ (α * Price) ┃ Emission (τ) ┃ α_in) ┃ (α_out) ┃ Supply (α) ┃ Tempo (k/n) +━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━ + 0 │ τ root │ 1.0000 τ/Τ │ τ 0.00 │ τ 0.0000 │ -, - │ Τ 0.00 │ 0.00 Τ /21M │ -/- + 2 │ β │ 0.0000 τ/β │ τ 1.00k │ τ 0.0000 │ τ 1.00k, │ 0.00 β │ 1.00k β │ 29/360 + │ awesome-fi… │ │ │ │ 1.00k β │ │ /21M │ + 1 │ α apex │ 0.0000 τ/α │ τ 11.00 │ τ 0.0000 │ τ 10.00, │ 1.00 α │ 11.00 α │ 29/100 + │ │ │ │ │ 10.00 α │ │ /21M │ +────────┼─────────────┼─────────────┼─────────────┼──────────────┼─────────────┼──────────────┼─────────────┼───────────── + 4 │ │ τ 1.0 │ │ τ 0.0 │ τ │ │ │ + │ │ │ │ │ 2.01k/29.00 │ │ │ + │ │ │ │ │ (6931.03%) │ │ │ +``` -### Burn cost +### Subnet creation cost -The burn cost for subnet creation is dynamic; it lowers gradually and doubles every time a subnet is created. +The cost for subnet creation is dynamic; it lowers gradually and doubles every time a subnet is created. -:::tip try it live +:::info +Note that this is labeled "burn cost", even though technically the cost of subnet creation is _recycled_, rather than _burned_. -Check the burn cost to create a subnet on Bittensor main network and test network: +See: [Glossary: Recycling and Burning](../resources/glossary#recycling-and-burning) +::: - - - +## Start emissions on the subnet -```shell -btcli subnet burn-cost --network finney -``` - - +To activate your subnet, beginning emissions and allowing staking, run: -```shell -btcli subnet burn-cost --network test ``` - - -::: - -## Fund your subnet - -To remedy your liquidity shortfall, transfer $\tau$ from the Alice account and try again. - -1. First, get the ss58 address for the destination wallet for the transfer: - ```shell - btcli w list - ``` - ```shell - ... - ── Coldkey sn-creator ss58_address 5C9xw4gDyu11ocdpWrmhT1sbi4xEHCpzEMsyMA4jGfAZQofQ - └── Hotkey default ss58_address 5GVsCAY6RuSuoAA1E77xsHJ9PjdZJjJrRkNFDxVtRKPnw7TR - ``` -1. Execute the transfer from alice to the sn-creator wallet - - ```console - btcli wallet transfer \ - --amount 1001 \ - --wallet.name alice \ - --destination "5GVsCAY6RuSuoAA1E77xsHJ9PjdZJjJrRkNFDxVtRKPnw7TR" \ - --subtensor.chain_endpoint ws://127.0.0.1:9945 - ``` - - ```shell - Do you want to transfer: - amount: τ 1,001.0000 - from: alice : 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY - to: 5GVsCAY6RuSuoAA1E77xsHJ9PjdZJjJrRkNFDxVtRKPnw7TR - for fee: τ 0.0001 [y/n]: y - 🌏 📡 Transferring... - ``` -## Success -Create some subnets. - -For example: - -```shell -btcli subnet create \ ---subnet-name awesome-first-subnet \ +btcli subnet start --netuid NETUID \ --wallet.name sn-creator \ ---subtensor.chain_endpoint ws://127.0.0.1:9945 +--network ws://127.0.0.1:9945 ``` -```console -Subnet burn cost: τ 1,000.0000 -Your balance is: τ 1,001.0000 -Do you want to burn τ 1,000.0000 to register a subnet? [y/n]:y -Enter your password: -Decrypting... -🌏 📡 Registering subnet.. -``` - -```shell - btcli subnet create \ ---subnet-name awesome-second-subnet \ ---wallet.name sn-creator \ ---subtensor.chain_endpoint ws://127.0.0.1:9945 -``` +Replace `NETUID` with the netuid of the subnet you want to enable emissions on. -```console -Subnet burn cost: τ 1,999.9405 -▰▱▱▱▱▱▱ 📡Retrieving lock cost from custom... -Your balance is: τ 2,003.0000 -Do you want to burn τ 1,999.9405 to register a subnet? [y/n]: Please enter Y or N -Do you want to burn τ 1,999.9405 to register a subnet? [y/n]: y -Enter your password: -Decrypting... -✅ Registered subnetwork with netuid: 3 -``` +After a while, you can confirm that the subnet's emissions have started by inspecting your subnet's token economy. You'll see a non-zero amount in the *Emission* column, indicating the subnet creator key accumulates emissions. -1. List your subnets +You can confirm the emissions by running the `btcli subnets list` command: -```shell -btcli subnet list \ ---subtensor.chain_endpoint ws://127.0.0.1:9945 -``` ```console Subnets Network: custom @@ -160,14 +96,29 @@ btcli subnet list \ Netuid ┃ Name ┃ (τ_in/α_in) ┃ (α * Price) ┃ Emission (τ) ┃ α_in) ┃ (α_out) ┃ Supply (α) ┃ Tempo (k/n) ━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━ 0 │ τ root │ 1.0000 τ/Τ │ τ 0.00 │ τ 0.0000 │ -, - │ Τ 0.00 │ 0.00 Τ /21M │ -/- - 2 │ β │ 1.0000 τ/β │ τ 1.00k │ τ 0.0000 │ τ 1.00k, │ 0.00 β │ 1.00k β │ 29/360 + 2 │ β │ 1.0000 τ/β │ τ 1.81k │ τ 1.0000 │ τ 1.00k, │ 414.00 β │ 1.81k β │ 29/360 │ awesome-fi… │ │ │ │ 1.00k β │ │ /21M │ - 3 │ γ │ 1.0000 τ/γ │ τ 1.00k │ τ 0.0000 │ τ 1.00k, │ 0.00 γ │ 1.00k γ │ 29/360 - │ awesome-se… │ │ │ │ 1.00k γ │ │ /21M │ - 1 │ α apex │ 1.0000 τ/α │ τ 11.00 │ τ 0.0000 │ τ 10.00, │ 1.00 α │ 11.00 α │ 29/100 + 1 │ α apex │ 0.0000 τ/α │ τ 11.00 │ τ 0.0000 │ τ 10.00, │ 1.00 α │ 11.00 α │ 29/100 │ │ │ │ │ 10.00 α │ │ /21M │ ────────┼─────────────┼─────────────┼─────────────┼──────────────┼─────────────┼──────────────┼─────────────┼───────────── - 4 │ │ τ 3.0 │ │ τ 0.0 │ τ │ │ │ - │ │ │ │ │ 2.01k/29.00 │ │ │ + 4 │ │ τ 1.0 │ │ τ 1.0 │ τ │ │ │ + │ │ │ │ │ 1.41k/562.00│ │ │ │ │ │ │ │ (6931.03%) │ │ │ -``` \ No newline at end of file +``` + +## Troubleshooting + +### Insufficient funds + +The coldkey signing the `subnet create` transaction must have a sufficient $\tau$ balance to cover the burn cost of subnet creation, so called because the funds cannot be recovered. + +```console +Subnet burn cost: τ 1,000.0000 +Your balance of: τ 0.0000 is not enough to burn τ 1,000.0000 to register a subnet. +``` + +To fix this, transfer TAO from the Alice account to cover this transaction and try again. For more information, see [Transfer TAO to wallets](./provision-wallets.md#transfer-tao-to-wallets). + +## Next steps + +With emissions now active on your subnet, you can begin registering and running miners and validators to participate in the network. diff --git a/docs/local-build/deploy.md b/docs/local-build/deploy.md index 3594d8b882..9a964f5d0d 100644 --- a/docs/local-build/deploy.md +++ b/docs/local-build/deploy.md @@ -1,100 +1,188 @@ --- -title: "Build and Deploy the Blockchain" +title: "Run a Local Bittensor Blockchain Instance" +toc_max_heading_level: 2 --- -# Deploy a Local Bittensor Blockchain Instance +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Heading from '@theme/Heading'; -This tutorial will guide the user through deploying a local instance of Subtensor, Bittensor's L1 blockchain. This is useful in general Bittensor development, as it gives you more freedom over chain state than when working against mainnet or even testnet. For example, it is much easier to create subnets without having to wait for registration availability. +# Run a Local Bittensor Blockchain Instance -Each local chain is provisioned with an `alice` account with one million $\tau$. +This tutorial will guide the user through running a local instance of Subtensor, Bittensor's L1 blockchain. Running a local instance of the Subtensor blockchain is a great way to test changes and explore the network in a safe and isolated environment. -In the following tutorial, we will also provision several wallets to serve as subnet creator, miner, and validator. +## Running a local subtensor instance -## Prerequisites +This section outlines steps for running a local instance of the Subtensor blockchain. There are two supported methods: -- Update your mac or linux workstation using your package manager -- Install [Bittensor SDK](../getting-started/installation) and [BTCLI](../getting-started/install-btcli) +- Using a prebuilt Docker image +- Running a local build from source +Both approaches enable isolated testing, development, and debugging without requiring a connection to the mainnet. Choose the method that best fits your workflow. -## Build your local Subtensor -### Install Rust/Cargo + + +Docker is the easiest way to set up a local Bittensor blockchain instance. It only takes a few minutes to get up and running with Docker. -To run locally, Substrate requires an up-to-date install of Cargo and Rust +The steps in this guide assume that you are running the command from the machine you intend to host from. -Install from Rust's website: -```shell -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` -Update your shell's source to include Cargo's path: +### Prerequisites -```shell -source "$HOME/.cargo/env" +Before you begin, make sure you have installed the following on your machine: + +- [Docker](https://docs.docker.com/desktop/use-desktop/) +- Install [Bittensor SDK](../getting-started/installation.md) and [Bittensor CLI](../getting-started/install-btcli.md) + +The Bittensor SDK and Bittensor CLI are required to interact with the local blockchain instance. + +### 1. Pull the Docker image + +You can pull the official subtensor Docker image used to create the local blockchain instance from the [GitHub Container Repository](https://github.com/opentensor/subtensor/pkgs/container/subtensor-localnet). To do this, run the following command in your terminal: + +```bash +docker pull ghcr.io/opentensor/subtensor-localnet:devnet-ready ``` -### Clone and tweak the Subtensor source +This command downloads the `subtensor-localnet` Docker image, making it available on your device. -We well clone the source and make a small modification to the state configuration with which the chain is deployed. +### 2. Run the container -Normally, the creation of new subnets is limited to one per day. This is inconvenient for local subnet development, so we will limit this restriction. +Subtensor can either be run in _fast blocks_ mode, which has advantages for development and testing purposes, or _non-fast blocks_. +Below are examples of how to run the container using each mode: +- Fast blocks: Fast block mode reduces block processing time to _250ms per block_, enabling rapid chain progression. It allows faster feedback cycles for operations such as staking, subnet creation, and registration, making them ideal for local testing scenarios. To run the container in fast block mode, run the following command in your terminal: + ```bash + docker run --rm --name local_chain -p 9944:9944 -p 9945:9945 ghcr.io/opentensor/subtensor-localnet:devnet-ready + ``` -1. Fetch the subtensor codebase to your local machine. +- Non-fast blocks: Non-fast block mode uses the default _12-second block time_, aligning with subtensor block intervals. While this mode utilizes the default block processing time, it also incorporates some enhancements—for example, subnets become eligible to start one minute after creation. To run the container in non-fast block mode, run the following command in your terminal: ```bash - git clone https://github.com/opentensor/subtensor.git + docker run --rm --name local_chain -p 9944:9944 -p 9945:9945 ghcr.io/opentensor/subtensor-localnet:devnet-ready False ``` -1. Open the source file `subtensor/runtime/src/lib.rs` in the your editor of choice, and find where the variable `SubtensorInitialNetworkRateLimit` is set. It is normally configured to 7200, which is the number of blocks per day written to the chain, i.e. the seconds in a day divided by 12, since a Subtensor block is written every twelve seconds. +:::info +By default, exiting the Docker container removes the image container with the local chain instance; thus, deleting the state of the local chain instance running on it. You can modify this behavior by when running the container wihtout the `--rm` flag. -In otherwords, this setting limits the number of new subnets that can be created to one per day. Let's change the value to 1 (block), so we can create a new subnet every 12 seconds if we want to. +For more information, see official [Docker documentation](https://docs.docker.com/reference/cli/docker/container/run/). +::: +### 3. Verify your setup -### Setup Rust +You can verify your local blockchain instance by checking the list of subnets available on your local blockchain. To do this, run the following command in the terminal: -This step ensures that you have the nightly toolchain and the WebAssembly (wasm) compilation target. Note that this step will run the Subtensor chain on your terminal directly, hence we advise that you run this as a background process using PM2 or other software. +```bash +btcli subnet list --network ws://127.0.0.1:9944 +``` -Update to the nightly version of Rust: +If the local blockchain is running correctly, you should see the following output: + +```console + Subnets + Network: custom + + + ┃ ┃ Price ┃ Market Cap ┃ ┃ ┃ ┃ ┃ + Netuid ┃ Name ┃ (τ_in/α_in) ┃ (α * Price) ┃ Emission (τ) ┃ P (τ_in, α_in) ┃ Stake (α_out) ┃ Supply (α) ┃ Tempo (k/n) +━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━ + 0 │ τ root │ 1.0000 τ/Τ │ τ 0.00 │ τ 0.0000 │ -, - │ Τ 0.00 │ 0.00 Τ /21M │ -/- + 1 │ α apex │ 1.0000 τ/α │ τ 11.00 │ τ 0.0000 │ τ 10.00, 10.00 α │ 1.00 α │ 11.00 α /21M │ 77/100 +────────┼────────┼─────────────┼─────────────┼──────────────┼────────────────────────┼───────────────┼──────────────┼───────────── + 2 │ │ τ 1.0 │ │ τ 0.0 │ τ 10.00/175.00 (5.71%) │ │ │ + +``` + + + + +### Prerequisites + +Before you begin, make sure you have installed the following on your machine: + +- Update your Mac or Linux workstation using your package manager +- Install [Bittensor SDK](../getting-started/installation) and [Bittensor CLI](../getting-started/install-btcli) + +The Bittensor SDK and Bittensor CLI are required to interact with the local blockchain instance. + +### Build your local Subtensor + +The following steps outline how to build a local subtensor instance: + +#### 1. Install Rust/Cargo + +To run locally, Substrate requires an up-to-date install of Cargo and Rust on your local machine. If Rust is already installed, update it using the following command: ```bash -./subtensor/scripts/init.sh +rustup update ``` -### Build +If Rust is not installed, install Rust and then update your shell's source to include Cargo's path by running the following commands: + +```shell +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +. "$HOME/.cargo/env" +``` -These steps initialize your local subtensor chain in development mode. These commands will set up and run a local subtensor. +#### 2. Clone the subtensor repo -Build the binary with the faucet feature enabled: +Next, you must fetch the subtensor codebase to your local machine. Run the following commands to clone the Github repo and navigate into the `subtensor` directory: ```bash +git clone https://github.com/opentensor/subtensor.git cd subtensor -cargo build -p node-subtensor --profile release ``` -### Run +Cloning the Subtensor repository provides all the necessary components to build and run the Bittensor blockchain locally. -Next, run the localnet script and turn off the attempt to build the binary (as we have already done this above): + + +#### 3. Setup Rust + +This step ensures that you have the nightly toolchain and the WebAssembly (wasm) compilation target. Note that this step will run the Subtensor chain directly on your terminal; therefore, we advise running it as a background process using PM2 or other software. + +Update to the nightly version of Rust: ```bash -BUILD_BINARY=0 ./scripts/localnet.sh +./subtensor/scripts/init.sh ``` -:::info troubleshooting -If you see errors to the effect that the release cannot be found in `targets/fast-blocks`, you may need to move the build artifacts from `targets/release` to `targets/fast-blocks/release`. -::: +#### 4. Run the blockchain locally +Use the `localnet.sh` script to build and launch a local instance of the subtensor blockchain. To run the blockchain: -## Validate +```bash +./scripts/localnet.sh +``` -Ensure your local chain is working by checking the list of subnets. +This script handles compilation and starts the node in a development-ready state. -Note the use of the `--chain_endpoint` flag to target the local chain, rather than, say, test network +:::info Additional configurations + +By default, running the `localnet.sh` script builds the Subtensor binary, purges any existing chain state, and launches the local blockchain in [fast block mode](../resources/glossary.md#fast-blocks). To run the local blockchain in [non-fast block mode](../resources/glossary.md#non-fast-blocks), run the following command in your terminal: + +```bash +./scripts/localnet.sh False +``` + +The script also supports additional flags to customize its behavior: + +- `--no-purge`: Skips deletion of the existing chain state, allowing you to resume from a previous session. +- `--build-only`: Compiles the binary and generates the chainspec without starting the node. + +These flags make it easy to adapt your localnet setup for different development workflows. +::: + +#### 5. Verify your setup + +Ensure your local chain is working by checking the list of subnets. ```shell - btcli subnet list --subtensor.chain_endpoint ws://127.0.0.1:9945 - btcli subnet list --network test +btcli subnet list --network ws://127.0.0.1:9945 ``` +If the local blockchain is running correctly, you should see the following output: + ```console Subnets Network: custom @@ -110,26 +198,16 @@ Note the use of the `--chain_endpoint` flag to target the local chain, rather th ``` +### Troubleshooting local chain issues -```shell -``` - -```console +If you encounter errors when running the local chain, consider the following: - Subnets - Network: test +- Fast and non-fast block modes are compiled into separate directories. Ensure you're using the correct build for your selected mode and that it has been compiled before starting the chain. +- Any time you pull updates or make changes to the _subtensor_ repository, you must rebuild the chain for those changes to take effect. + + - ┃ ┃ Price ┃ Market Cap ┃ ┃ ┃ ┃ ┃ - Netuid ┃ Name ┃ (τ_in/α_in) ┃ (α * Price) ┃ Emission (τ) ┃ P (τ_in, α_in) ┃ Stake (α_out) ┃ Supply (α) ┃ Tempo (k/n) -━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━ - 0 │ τ root │ 1.0000 τ/Τ │ τ 5.01m │ τ 0.0000 │ -, - │ Τ 3.10m │ 5.01m Τ /21M │ -/- - 277 │ इ muv │ 0.4008 τ/इ │ τ 536.06k │ τ 0.4154 │ τ 199.85k, 498.63k इ │ 838.83k इ │ 1.34m इ /21M │ 39/99 - 3 │ γ templar │ 0.1534 τ/γ │ τ 219.03k │ τ 0.1690 │ τ 110.74k, 722.13k γ │ 706.14k γ │ 1.43m γ /21M │ 65/99 - 119 │ Ⲃ vida │ 0.0748 τ/Ⲃ │ τ 94.83k │ τ 0.1321 │ τ 44.77k, 598.65k Ⲃ │ 669.45k Ⲃ │ 1.27m Ⲃ /21M │ 81/99 - 1 │ α apex │ 0.0587 τ/α │ τ 70.03k │ τ 0.0405 │ τ 30.27k, 515.71k α │ 677.20k α │ 1.19m α /21M │ 63/99 - 13 │ ν dataverse │ 0.0467 τ/ν │ τ 63.12k │ τ 0.0645 │ τ 26.93k, 576.17k ν │ 774.11k ν │ 1.35m ν /21M │ 75/99 - 255 │ ዉ ethiopic_wu │ 0.0181 τ/ዉ │ τ 21.94k │ τ 0.0133 │ τ 10.72k, 592.40k ዉ │ 619.73k ዉ │ 1.21m ዉ /21M │ 17/99 +## Next steps -... -``` +Once your local chain is running, the next step is to provision wallets for local deployment. This includes creating hotkeys and coldkeys, funding wallets, and preparing accounts for testing or development tasks. For more information, see [Provision Wallets for Local Development](./provision-wallets). diff --git a/docs/local-build/mine-validate.md b/docs/local-build/mine-validate.md index 9c0efd4435..59e2700b01 100644 --- a/docs/local-build/mine-validate.md +++ b/docs/local-build/mine-validate.md @@ -1,125 +1,342 @@ --- -title: "Mine and Validate (Locally)" +title: "Mining and Validating on Localnet" --- -# Mine and Validate (Locally) +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -This page continues the tutorial series on local Bittensor development. In this installment, we will deploy minimal, local servers for a miner and validators, serving requests, setting weights, and earning emissions. +# Mining and Validating on Localnet +This page walks through mining and validating on a local Bittensor network. It covers how to register a neuron on a subnet, then run the miner and validator scripts to begin earning emissions. + +For mining and validating on the Bittensor mainnet, see [Mining in Bittensor](../miners/index.md) and [Validating in Bittensor](../validators/index.md). ## Prerequisites +Before continuing with the rest of this tutorial, make sure you've completed the following: + - [Deploy a Subtensor chain locally](./deploy) -- [Provision wallets for the sn-creator, miner, and validator users for this tutorial.](./provision-wallets) -- [Create a Subnet on your local chain](./create-subnet) +- [Provision wallets for the subnet creator, miner, and validator users for this tutorial.](./provision-wallets) +- [Created and started a subnet](./create-subnet) to enable emissions. + +This guide uses Opentensor's [_subnet template_](https://github.com/opentensor/subnet-template/tree/main) repo. The repo provides a minimal implementation for building a custom subnet on the Bittensor network and includes the core logic for the miner and validator. -## Register the Miner and Validator +## 1. Register the neuron hotkeys -Register the subnet miner and validator with the following commands: +To participate in a subnet, you must first register a hotkey on it. This registration assigns the wallet a unique identifier (UID), which is required to interact with and receive emissions from the subnet. + +To register the hotkey, run the following command in your terminal, replacing `NETUID`, `WALLET_NAME`, and `WALLET_HOTKEY` with the target subnet ID, the name of the wallet, and the associated hotkey, respectively, as shown: ```bash -btcli subnet register \ ---wallet.name validator \ ---wallet.hotkey default \ ---subtensor.chain_endpoint ws://127.0.0.1:9945 +btcli subnets register --netuid NETUID \ +--wallet-name WALLET_NAME \ +--hotkey WALLET_HOTKEY \ +--network ws://127.0.0.1:9945 +``` + +You will be prompted to confirm the registration fee and enter your wallet password to authorize the transaction. + +
+Show Sample Output + +```console +Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:88 +Using the specified network local from config + + Register to netuid: 2 + Network: local + + Netuid ┃ Symbol ┃ Cost (Τ) ┃ Hotkey ┃ Coldkey +━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + 2 │ β │ τ 0.0985 │ 5FErfAJc3Wf32TVLQTtM....TRTrgMF4sjYWfq49oMCxXxqS │ 5Gxhv5iZGBvvR6YJeEdLmvZ7hS....dHc43fLqMVkhki7j4 +────────┼────────┼──────────┼──────────────────────────────────────────────────┼────────────────────────────────────────────────── + │ │ │ │ +Your balance is: 99,999.9000 τ +The cost to register by recycle is 0.0985 τ +Do you want to continue? [y/n] (n): y +Enter your password: +Decrypting... +Balance: + 99,999.9000 τ ➡ 99,999.8015 τ +✅ Registered on netuid 3 with UID 2 +``` + +
+ +Repeat the registration process for both the miner and validator hotkeys. + +To confirm the registration of your hotkeys in the subnet, run the following command in your terminal: + +```sh +btcli subnet show --netuid NETUID --network ws://127.0.0.1:9945 +``` + +The command returns detailed information about a subnet including its registered neurons and their state. + +
+Show Sample Output + +```console + +Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:89 + + + + Subnet 2: New subnet + Network: local + + UID ┃ Stake (β) ┃ Alpha (β) ┃ Tao (τ) ┃ Dividends ┃ Incentive ┃ Emissions (β) ┃ Hotkey ┃ Coldkey ┃ Identity +━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━ + 0 │ 5.04 β │ 5.04 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 9.017303 β │ 5DFZTw │ 5Dc1Qu │ (*Owner controlled) + 1 │ 0.00 β │ 1.00 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5FErfA │ 5GxHV5 │ ~ + 2 │ 0.00 β │ 1.00 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5GRLEv │ 5EnNgi │ ~ +─────┼───────────┼───────────┼─────────┼───────────┼───────────┼───────────────┼────────┼─────────┼───────────────────── + │ 5.04 β │ 5.04 β │ 0.00 β │ 0.000 │ │ 9.017303 β │ │ │ + + +Subnet 2: New subnet + Owner: 5Dc1Qu2pDfWuDzt3c5wJV2LxRXAmVqZYsAib72e59H3vnRVn + Rate: 1.0056 τ/β + Emission: τ 0.0000 + TAO Pool: τ 1.10k + Alpha Pool: 1.10 β + Tempo: 8/360 + Registration cost (recycled): τ 0.0845 + ``` + +
+ +## 2. Acquire validator permit + +To qualify as a validator on a subnet, a registered node must have a validator permit. This permit allows nodes to submit miner evaluations and set weights on a subnet. For more information, see [validator permits](../validators/index.md#requirements-for-validation). + +To get validator permits on the demo subnet, you need to stake sufficient TAO to the validator hotkey. To do this, run the following command in the terminal: + ```bash -btcli subnet register \ ---netuid 2 \ ---wallet.name miner \ ---wallet.hotkey default \ ---subtensor.chain_endpoint ws://127.0.0.1:9945 +btcli stake add --netuid NETUID \ +--wallet-name WALLET_NAME \ +--hotkey WALLET_HOTKEY \ +--partial \ +--network ws://127.0.0.1:9945 ``` +Replace `NETUID`, `WALLET_NAME`, and `WALLET_HOTKEY` with the target subnet ID, the name of the wallet, and the associated hotkey, respectively. +Once you've staked enough TAO to the validator hotkey, the validator becomes eligible to submit evaluations and set weights on the subnet. You can verify that the validator has been granted a permit using any of the following methods: -### Troubleshoot -#### Insufficient funds -If you have not added TAO to your validator wallet, you'll see an error like the following: + + +Run the following command in the terminal: +```bash +btcli wallet overview --wallet.name WALLET_NAME --network ws://127.0.0.1:9945 +``` +Replace the `WALLET_NAME` with the name of the validator wallet. + +
+Show Sample Output ```console -Insufficient balance τ 0.0000 to register neuron. Current recycle is τ 1.0000 TAO +Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:88 +Using the specified network local from config + Wallet + + test-validator : 5Gxhv5iZGBvvR6YJeEd...bE6FdHc43fLqMVkhki7j4 + Network: local +Subnet: 2: New subnet β + + COLDKEY HOTKEY UID ACTIVE STAKE(β) RANK TRUST CONSENSUS INCENTIVE DIVIDENDS EMISSION(… VTRUST VPE… UPDAT… AXON HOTKEY_SS58 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + test-validator test-validator 1 False 287.57 0.00 0.00 0.00 0.00 0.00 38841066.… 0.00 * 5908 none 5FErfAJc3W + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + 1 287.57 β 0.0000 0.0000 0.0000 0.0000 0.0000 ρ38841066 0.0000 + + Wallet free balance: 99,994.3638 τ ``` -Transfer funds from the Alice account to cover it and try again. Consult `btcli w list` and carefully check the ss58 address of the destination coldkey (in this case, the one with the name `validator`). -```shell -btcli wallet transfer \ ---amount 11 \ ---wallet.name alice \ ---destination "5EEy34..." \ ---subtensor.chain_endpoint ws://127.0.0.1:9945 +
+ +If the validator wallet has a validator permit, an asterisk (`*`) is shown under the `VPERMIT` column for the corresponding subnet in the response table. + +
+ +Input the following lines in your Python environment, replacing `NETUID`, `WALLET_NAME`, and `WALLET_HOTKEY` with the target subnet ID, the name of the wallet, and the associated hotkey, respectively. + +```python +import bittensor as bt +network=bt.subtensor(network="local") +subnet = network.metagraph(NETUID) +wallet = bt.wallet( name = 'WALLET_NAME', hotkey = 'HOTKEY' ) +my_uid = subnet.hotkeys.index( wallet.hotkey.ss58_address ) +print(f'Validator permit: {subnet.validator_permit[my_uid]}') ``` +The command outputs `True` or `False` depending on whether the validator hotkey has a permit. + +
+ +:::info Validator Permits on Localnet Subnets +On localnet subnets, competition for permits is typically minimal. After staking TAO to the validator hotkey, the neuron should become eligible for a validator permit. If it does not yet have one, wait until the end of the subnet’s tempo. +::: + +## 3. Pull the `subnet-template` repo + +The `subnet-template` repo contains the core logic for the subnet miner and validator. It features a simple `dummy` protocol where miners multiply input values by 2, while validators evaluate responses and update network weights based on performance. -### Successful registration +To begin, clone the subnet-template GitHub repository and navigate into its directory: + +```sh +git clone https://github.com/opentensor/subnet-template.git +cd subnet-template +``` + +## 4. Run the miner and validator + +After getting the validator permits, you can now run the validator alongside the miner to begin participating in the subnet. + +Begin by starting the miner process to produce and submit work to the subnet. Then, run the validator process on a different terminal tab to evaluate miner outputs and set weights for the network. + +:::info +To ensure proper operation, run the miner and validator processes concurrently, each in a separate terminal tab or session. +::: + +### Start the miner process + +To start the miner, run the following Python script in the `subnet-template` directory: + +```sh +python miner.py \ + --wallet.name WALLET_NAME \ + --wallet.hotkey HOTKEY \ + --netuid NETUID \ + --axon.port 8901 \ + --subtensor.network local +``` + +The script launches an Axon server on port `8901`, which the miner uses to receive incoming requests from validators. + +### Start the validator process + +To start the validator process, run the following Python script in the `subnet-template` directory: + +```sh +python validator.py \ + --wallet.name WALLET_NAME \ + --wallet.hotkey HOTKEY \ + --netuid NETUID \ + --subtensor.network local +``` + +This script begins the process of sending inputs to the miners and setting weights based on miner responses. + +:::info miner and validator logs +Use the `--logging.info` flag to print miner and validator log messages directly to the console. This helps you monitor activity in real time. +::: + +## 5. Check your emissions + +After weights have been successfully set on the subnet, you can check the updated emissions distribution at the end of the subnet's [tempo](../resources/glossary.md#tempo). + +To check the subnet's emissions, run the following command in the terminal: + +```sh +btcli subnet show --netuid NETUID --network ws://127.0.0.1:9945 +``` + +The command returns detailed information about a subnet, including its registered neurons, their current state, and updated emission earnings. + +
+Show Sample Output -Repeat the above steps to successfully register your miner and validator once they are funded ```console -netuid: 2 +Using the specified network local from config +Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:89 - Register to netuid: 2 - Network: custom - Netu… ┃ Sym… ┃ Cost (… ┃ Hotkey ┃ Coldkey -━━━━━━━╇━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - 2 │ β │ τ 1.00… │ 5CffqSVhydFJHBSbbgfVLAVkoNBTsv3wLj2Tsh1cr2kfa… │ 5EEy34R4gfXe5SG62nz1nDuh3KAovRLpKLm4ccSv7qkNhn… -───────┼──────┼─────────┼────────────────────────────────────────────────┼───────────────────────────────────────────────── - │ │ │ │ -Your balance is: τ 11.0000 -The cost to register by recycle is τ 1.0000 -Do you want to continue? [y/n] (n): y -Enter your password: -Decrypting... -Balance: - τ 11.0000 ➡ τ 10.0000 -✅ Registered on netuid 2 with UID 1 -▰▱▱▱▱▱▱ 📡 Recycling TAO for Registration... + + Subnet 2: New subnet + Network: local + + UID ┃ Stake (β) ┃ Alpha (β) ┃ Tao (τ) ┃ Dividends ┃ Incentive ┃ Emissions (β) ┃ Hotkey ┃ Coldkey ┃ Identity +━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━ + 0 │ 109.80 β │ 109.80 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5DFZTw │ 5Dc1Qu │ (*Owner controlled) + 1 │ 354.68 β │ 354.68 β │ τ 0.00 │ 1.000000 │ 0.000000 │ 148.010826 β │ 5FErfA │ 5Gxhv5 │ Test validator + 2 │ 148.01 β │ 148.01 β │ τ 0.00 │ 0.000000 │ 1.000000 │ 148.010826 β │ 5GRLEv │ 5EnNgi │ Test miner +─────┼───────────┼───────────┼─────────┼───────────┼───────────┼───────────────┼────────┼─────────┼───────────────────── + │ 612.49 β │ 612.49 β │ 0.00 β │ 1.000 │ │ 296.0217 β │ │ │ + + +Subnet 2: New subnet + Owner: 5Dc1Qu2pDfWuDzt3c5wJV2LxRXAmVqZYsAib72e59H3vnRVn + Rate: 1.0054 τ/β + Emission: τ 0.0000 + TAO Pool: τ 1.62k + Alpha Pool: 1.61k β + Tempo: 23/360 + Registration cost (recycled): τ 0.1000 + ``` -### Check your registration +Note the increase in the miner neuron's `Incentive` column and the validator neuron's `Dividend` column as well as the `Emissions` on both neurons. + +
+ +For more information on a subnet's emission distribution, see [Emissions](../learn/emissions.md). + +## Troubleshooting errors -Confirm your registration on the subnet with the following command: +This section discusses errors that could arise while running the validator or miner, and provides steps to diagnose and resolve them. -```shell -btcli wallet overview --wallet.name validator --subtensor.chain_endpoint ws://127.0.0.1:9945 +**Insufficient funds** -btcli wallet overview --wallet.name miner --subtensor.chain_endpoint ws://127.0.0.1:9945 +The coldkey signing the `btcli subnet register` transaction must have a sufficient $\tau$ balance to cover the recycling cost of the registration. +
+Show sample error + +```console +Insufficient balance 0.0000 τ to register neuron. Current recycle is 0.0970 τ TAO. ``` +
+ +**Unregistered miner or validator** + +This occurs when you attempt to run a miner or validator on a subnet where it is not registered. + +
+Show sample error + ```console - Wallet +Your miner: Wallet (Name: 'test-miner', Hotkey: 'test-miner', Path: '~/.bittensor/wallets/') is not registered to chain connection: Network: local, Chain: ws://127.0.0.1:9944  +Run 'btcli register' and try again. +``` - validator : 5EEy34R4gfXe5SG62nz1nDuh3KAovRLpKLm4ccSv7qkNhnqw - Network: custom -Subnet: 2: awesome-first-subnet β +
- COLDKEY HOTKEY UID AC… STA… RANK TRU… CON… INC… DIV… EMI… VTR… … U… AXON HOTKE… - ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - valida… default 1 Tr… 0.00 0.00 0.00 0.00 0.00 0.00 0.0… 0.00 51 none 5Cffq… - ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - 1 0.0… 0.0… 0.0… 0.0… 0.0… 0.0… ρ0 0.0… +**`NeuronNoValidatorPermit`** +This means that the neuron is attempting to set weights without a validator permit. Try fix this, you must stake sufficient TAO to the validator hotkey and wait till the end of the subnet's tempo. - Wallet balance: τ10.0 +
+Show sample error - Wallet +```console +Failed set weights. Error: Subtensor returned `NeuronNoValidatorPermit(Module)` error. This means: `The caller is attempting to set non-self weights without being a permitted validator. | Please consult https://docs.bittensor.com/errors/subtensor#neuronnovalidatorpermit`. +``` - miner : 5DA7UsaYbk1UnhhtTxqpwdqjuxhQ2rW7D6GTN1S1S5tC2NRV - Network: custom -Subnet: 2: awesome-first-subnet β +
- COLDKEY HOTKEY UID AC… STA… RANK TRU… CON… INC… DIV… EMI… VTR… … U… AXON HOTKE… - ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - miner default 2 Tr… 0.00 0.00 0.00 0.00 0.00 0.00 0.0… 0.00 22 none 5Capz… - ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - 1 0.0… 0.0… 0.0… 0.0… 0.0… 0.0… ρ0 0.0… +**`WeightVecLengthIsLow`** +This error occurs when the validator attempts to set weights for fewer elements than allowed. It often happens when all neurons in the subnet are unresponsive, causing the validator to try setting zero weights for each of them. - Wallet balance: τ10.0 +
+Show sample error + +```console +Error: Subtensor returned `WeightVecLengthIsLow(Module)` error. This means: `The dispatch is attempting to set weights on chain with fewer elements than are allowed. | Please consult https://docs.bittensor.com/errors/subtensor#weightveclengthislow`. ``` -```shell -python3 neurons/miner.py netuid=2 -chain_endpoint=ws://127.0.0.1:9945 wallet_name=miner wallet_hotkey=default -``` \ No newline at end of file +
diff --git a/docs/local-build/provision-wallets.md b/docs/local-build/provision-wallets.md index 89611deee8..03a9e62a34 100644 --- a/docs/local-build/provision-wallets.md +++ b/docs/local-build/provision-wallets.md @@ -8,69 +8,89 @@ Now that your local Subtensor chain is deployed, you can provision wallets to se Every local blockchain is pre-provisioned with an "Alice" account, which is loaded with one million $\tau$. +## Prerequisites + +To follow along with the rest of this tutorial, ensure that you have a local chain running. To set up a local chain, see [Create a local blockchain instance](./deploy.md). + ## Access the Alice account To access the handy pre-provisioned development "Alice" account on your local chain, use: + ```shell btcli wallet create --uri alice ``` -Confirm Alice's massive $\tau$ bag. +Next, you will be prompted to configure the wallet by setting a name for the wallet's coldkey and hotkey. -```shell - btcli w balance --wallet.name alice --subtensor.chain_endpoint ws://127.0.0.1:9945 +:::tip +To access the 'Alice' wallet, you must use the assigned coldkey name and include the local subtensor chail URL as shown + +```sh +btcli wallet balance --wallet.name alice --network ws://127.0.0.1:9945 ``` +The following should be returned in the console: + ```console Wallet Coldkey Balance Network: custom - Wallet Name Coldkey Address Free Balance Staked Value Staked (w/slippage) Total Balance Total (w/slippage) + Wallet Name Coldkey Address Free Balance Staked Value Total Balance ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - alice 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY τ 999,999.8999 τ 0.0000 τ 0.0000 τ 999,999.8999 τ 999,999.8999 - + alice 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY 1,000,000.0000 τ 0.0000 τ 1,000,000.0000 τ - Total Balance τ 999,999.8999 τ 0.0000 τ 0.0000 τ 999,999.8999 τ 999,999.8999 + Total Balance 1,000,000.0000 τ 0.0000 τ 1,000,000.0000 τ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` +::: + ## Provision wallets -You will need wallets for the different personas, i.e., subnet owner, subnet validator and subnet miner, in the subnet. +To proceed with this tutorial, you’ll need to create separate wallets for each role on the Bittensor blockchain. Specifically, create three wallets: one each for the subnet owner, validator, and miner. -- The owner wallet creates and controls the subnet. -- The validator and miner will be registered to the subnet created by the owner. This ensures that the validator and miner can run the respective validator and miner scripts. +- The subnet owner wallet creates and controls the subnet—`sn-creator`. +- The validator and miner wallets will be registered on the created subnet—`test-validator` and `test-miner`. -### Create a coldkey-only wallet for the subnet creator role (they do not need a hotkey): +Using separate wallets for each role ensures they can independently run their respective processes and scripts. + +To create a wallet, run the following command in your terminal: ```bash -btcli wallet new_coldkey \ ---wallet.name sn-creator +btcli wallet create \ +--wallet.name WALLET_NAME \ +--hotkey WALLET_HOTKEY \ +--network ws://127.0.0.1:9945 ``` -### Set up the miner's wallet with a coldkey and hotkey: +Replace `WALLET_NAME` and `WALLET_HOTKEY` with the appropriate identifiers for each role—subnet creator, miner, or validator. -```bash -btcli wallet new_coldkey \ ---wallet.name miner -``` +### Transfer TAO to wallets -```bash -btcli wallet new_hotkey \ ---wallet.name miner \ ---wallet.hotkey default +After creating your wallets, transfer some TAO from the `Alice` account to them to cover the transaction fees required for onchain operations. To transfer TAO, run the following command in your terminal: +```sh +btcli wallet transfer \ +--wallet.name alice \ +--destination DESTINATION_ADDRESS \ +--network ws://127.0.0.1:9945 ``` -### Set up the validator's wallet with a coldkey and hotkey: +Replace `DESTINATION_ADDRESS` with the wallet address you want to send the TAO to. -```bash -btcli wallet new_coldkey \ ---wallet.name validator -``` -```bash -btcli wallet new_hotkey \ ---wallet.name validator \ ---wallet.hotkey default +:::info +Run the `btcli wallets list` command and carefully check the ss58 address of the destination coldkey that you want to fund. +::: + +To confirm your wallet balances, run the following command in your terminal: + +```sh +btcli wallet balance --wallet.name WALLET_NAME --network ws://127.0.0.1:9945 ``` + +## Next steps + +Now that you have created the necessary wallets and funded them with TAO, you can proceed to create a subnet on the local chain. This will enable you to register validators and miners, configure subnet parameters, and begin participating in the network’s consensus and emissions processes. + +To begin, see [Create a subnet locally](create-subnet.md). diff --git a/docs/media-assets.md b/docs/media-assets.md deleted file mode 100644 index 31e39f131b..0000000000 --- a/docs/media-assets.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: "Media Assets" ---- - -# Media Assets - -Download the Bittensor media assets from the below location: - -**Location**: https://github.com/opentensor/developer-docs/tree/main/static/bittensor-media-assets - -**Description**: A zip file (29 MB) containing Bittensor TAO symbol, monogram, logotype, supporting elements and a Opentensor brand guidelines PDF. \ No newline at end of file diff --git a/docs/migration_guide.md b/docs/migration_guide.md deleted file mode 100644 index a67ca2c2b8..0000000000 --- a/docs/migration_guide.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: "Bittensor 9.0 Migration Guide" ---- -# Bittensor 9.0 Migration Guide - -This page notes breaking changes for the Bittensor Python SDK `v9.0`. This version supports Dynamic TAO, a major evolution of the Bittensor network's tokenomic architecture. - -See: [Dynamic TAO: What to expect](../dynamic-tao). - -**Contents:** -- [`Subtensor`: removed functions](#subtensor-removed-functions) -- [`Subtensor`: type changes](#subtensor-type-changes) -- [`AsyncSubtensor` parity with `Subtensor`](#asyncsubtensor) -- [`py-substrate-interface` replaced with `async-substrate-interface`](#py-substrate-interface-replaced-with-async-substrate-interface) - -See: [Concurrency with AyncIO and AsyncSubtensor](./subnets/asyncio) - -## Subtensor: removed functions - -### `get_account_next_index` - -This was only used for getting nonce, which can be achieved with `subtensor.substrate.get_account_next_index(hotkey.ss58_address)`. - -### `get_prometheus_info` - -We no longer use prometheus info. - -### `get_total_stake_for_coldkey` - -Not compatible with Dynamic TAO. - -Replaced with [`get_stake`](./dynamic-tao/sdk-cheat-sheet#get_stake), which returns a staked balance for a coldkey, hotkey pair on a specific subnet. - -### `get_total_stake_for_coldkeys` - -Not compatible with Dynamic TAO. - -Replaced with [`get_stake`](./dynamic-tao/sdk-cheat-sheet#get_stake), which returns a staked balance for a coldkey, hotkey pair on a specific subnet. - -### `get_total_stake_for_hotkey` - -Not compatible with Dynamic TAO. - -Replaced with [`get_stake`](./dynamic-tao/sdk-cheat-sheet#get_stake), which returns a staked balance for a coldkey, hotkey pair on a specific subnet. - -### `get_total_stake_for_hotkeys` - -Not compatible with Dynamic TAO. - -Replaced with [`get_stake`](./dynamic-tao/sdk-cheat-sheet#get_stake), which returns a staked balance for a coldkey, hotkey pair on a specific subnet. - -## Subtensor: type changes - -### `__init__` -No longer takes `connection_timeout` or `websocket` args. This is due to `py-substrate-interface` being re-written as `async-substrate-interface`. - -### `amount` - -All Subtensor methods that accept an `amount` arg now accept it only as a `Balance` object, rather than the previous `Union[Balance, int, float]`. - -New helper functions, `tao` and `rao` in `bittensor.utils.balance`, return a `balance` object from the given Tao or Rao amount. - -These methods include the following, and their associated extrinsics: - - `transfer` - - `unstake` - - `add_stake` - - `move_stake` - - `swap_stake` - - `transfer_stake` - - `get_transfer_fee` - - -For example, where `transfer` previously accepted float for the amount, it now takes a `Balance` object, which can be created on the fly: - -**Previously:** -```python -from bittensor.core.subtensor import Subtensor - -subtensor = Subtensor() -subtensor.transfer(wallet, destination, 1.0) -``` - -**Now written as:** - -```python -from bittensor.core.subtensor import Subtensor -from bittensor.utils.balance import tao, rao - -subtensor = Subtensor() -subtensor.transfer(wallet, destination, tao(1.0)) -# or -subtensor.transfer(wallet, destination, rao(1000000000)) -``` - -### consolidation of arg label: `block` -There were some cases where the block arg was called `block_number` or `block_id`. This is standardised, and now all block args are called `block`. - -### `get_block_hash` - -No longer requires `block` arg, will fetch the latest block if not specified. - -### `get_stake_for_coldkey_and_hotkey` - -Arg order has changed. It now takes `(coldkey, hotkey)` to align with the method name. - -In addition, to accomodate changes to staking in dynamic TAO, the function now also accepts an optional list of `netuids` to check for stake, and returns a `dict[int, StakeInfo]`, where `int` is the netuid. If `netuids` is left as `None`, all netuids are fetched. - -### `get_subnet_reveal_period_epochs` - -Type hint is updated to reflect it always returns an `int`, rather than an `Optional[int]`. - -### `query_runtime_api` - -Now accepts params as `Any`, returns `Any`. This is due to an update in `bt-decode` and `async-substrate-interface` that allows for arbitrary decoding of runtime calls. - -### `get_subnet_burn_cost` - -Now returns an `Optional[Balance]` object rather than `Optional[int]` (previously it gave rao `int`) - -### `get_children` - -Now returns `tuple[bool, list[tuple[float, str]], str]` instead of `tuple[bool, list[tuple[int, str]], str]`, as the proportions are now normalised floats. - -## `AsyncSubtensor` - -`AsyncSubtensor` and `Subtensor` now have all and only the same methods. - -Check out the wiki entry on [Concurrency in Bittensor](https://github.com/opentensor/bittensor/wiki/Concurrency-in-Bittensor) to learn more. - -## `py-substrate-interface` replaced with `async-substrate-interface` - -`py-substrate-interface` has been completely removed as a requirement, and has been rewritten as `async-substrate-interface`. - -While the main goal of this project was initially just providing an AsyncIO-compatible version of `py-substrate-interface` for our use in `btcli` and `AsyncSubtensor`, we noticed a lot of room for improvement, so we wrote not only the async part, but also a synchronous part. We aimed to be as API-compatible as possible, but there are a few differences (mainly in runtime calls). - -`async-substrate-interface` is its own standalone package, as is a requirement for `bittensor` and `btcli`, replacing `py-substrate-interface`. - -While we do practically all the decoding now through `bt-decode`, we still use `py-scale-codec` for a few `SCALE` encodings. This package will also eventually be replaced by an updated version of `bt-decode`. - -Check out the wiki entry on [Concurrency in Bittensor](https://github.com/opentensor/bittensor/wiki/Concurrency-in-Bittensor) to learn more. diff --git a/docs/miners/autostaking.md b/docs/miners/autostaking.md new file mode 100644 index 0000000000..e8d135f9c6 --- /dev/null +++ b/docs/miners/autostaking.md @@ -0,0 +1,180 @@ +--- +title: "Auto Staking for Miners" +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Auto Staking for Miners + +Auto staking allows miners to automatically stake their mining income to a validator of their choice, streamlining the process of compound staking without manual intervention. + +## Overview + +The auto staking feature enables miners to set a destination validator where their mining emissions will be automatically staked. This eliminates the need for manual staking operations and ensures that mining rewards are continuously reinvested into the network. + +When auto staking is set, as a miner earns emissions from your subnet participation, their emissions are automatically staked to a specified validator. This conveniently allows miners to grow their stake as they earn it, without the need for repetitive manual stake movement operations. + +### How It Works On Chain + +On the Bittensor blockchain (Subtensor), the `AutoStakeDestination` chain state variable holds autostaking destination hotkeys for each netuid, for each wallet that sets them. + +Setting your wallet's auto stake destinations is mostly easily done with BTCLI or the Bittensor Python SDK, as described below, but can also be set through the `set_coldkey_auto_stake_hotkey` extrinsic (call index 114). + +See [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/macros/dispatches.rs#L2206). + +### Prerequisites + +- A wallet +- A target hotkey to receive the auto-staked TAO (can be any hotkey, including the miner's own hotkey) + +:::info Coldkey Swap Integration + +When a coldkey is swapped, the auto-stake destination is automatically transferred to the new coldkey, ensuring continuity of auto-staking functionality. + +::: + +## Managing Auto Staking + +You can view and set auto-stake destinations directly from the Bittensor CLI or Bittensor SDK. + +### View current auto-stake destinations + +Shows the target hotkey per subnet for a given coldkey. If none is set, the output notes the default behavior. + + + + +```bash +# By wallet name (uses your configured wallet path) +btcli stake auto --wallet.name + +# By coldkey SS58 address +btcli stake auto --ss58 +``` + +```console +btcli stake auto --wallet.name alice --network local +``` + +```console + Auto Stake Destinations for alice + Network: local + Coldkey: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + + Netuid Subnet Status Destination Hotkey Identity +───────────────────────────────────────────────────────────────────────── + 0 root Default + 1 apex Default + 2 zawesome-first-su... Default + +Total subnets: 3 Custom destinations: 0 +``` + + + + + +```python +import asyncio +import bittensor as bt + +async def main(): + async with bt.AsyncSubtensor(network="local") as subtensor: + coldkey_ss58 = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" # This is the Alice key, replace with your coldkey SS58 + pairs = await subtensor.get_auto_stakes(coldkey_ss58=coldkey_ss58) + if not pairs: + print("No auto-stake destinations set.") + else: + for netuid, hotkey in pairs.items(): + print(f"netuid {netuid}: {hotkey}") + +asyncio.run(main()) +``` + +```shell +netuid 1: 5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM +netuid 2: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY +``` + + + + +### Set auto-stake destination + +Sets the destination hotkey for your coldkey on a specific subnet. + + + + +```bash +btcli stake set-auto --wallet.name --netuid +``` + +For example + +```shell +btcli stake set-auto --wallet.name alice --network local +``` + +```console +Using the wallet path from config: /Users/michaeltrestman/.bittensor/wallets +Enter the netuid to configure (1): 2 +Enter the hotkey ss58 address to auto-stake to (Press Enter to view delegates): + + Subnet 2: zawesome-first-su... + Network: local • Mechanism 0 + + UID ┃ Stake (β) ┃ Alpha (β) ┃ Tao (τ) ┃ Dividends ┃ Incentive ┃ Emissions (β) ┃ Hotkey ┃ Coldkey ┃ Identity +━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━ + 0 │ 8.38k β │ 8.38k β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5Grwva │ 5Grwva │ (*Owner controlled) + 2 │ 13.38k β │ 13.38k β │ τ 0.00 │ 0.000000 │ 0.000000 │ 9.020050 β │ 5CffqS │ 5EEy34 │ ~ + 1 │ 0.00 β │ 0.00 β │ τ 0.00 │ 0.000000 │ 0.000000 │ 0.000000 β │ 5Capz7 │ 5DA7Us │ ~ +─────┼───────────┼───────────┼─────────┼───────────┼───────────┼───────────────┼────────┼─────────┼───────────────────── + │ 21.77k β │ 21.77k β │ 0.00 β │ 0.000 │ │ 9.0201 β │ │ │ + +Enter the UID of the delegate you want to stake to (or press Enter to cancel): 2 + +Selected delegate: 5CffqSVhydFJHBSbbgfVLAVkoNBTsv3wLj2Tsh1cr2kfanU6 + + Confirm Auto-Stake Destination + Netuid Subnet Destination Hotkey Identity +───────────────────────────────────────────────────────────────────────────────────────────── + 2 zawesome-first-su... 5CffqSVhydFJHBSbbgfVLAVkoNBTsv3wLj2Tsh1cr2kfanU6 + +Set this auto-stake destination? [y/n] (y): y +✅Your extrinsic has been included as 20979-1 +✅ Auto-stake destination set for netuid 2 +``` + + + + +```python +import asyncio +import bittensor as bt + +async def main(): + async with bt.async_subtensor(network="local") as subtensor: + wallet = bt.wallet( + name="Alice", + ) + wallet.unlock_coldkey() + + netuid = 2 # subnet to configure + hotkey_ss58 = "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" # validator hotkey to auto-stake to + + success, msg = await subtensor.set_auto_stake( + wallet=wallet, + netuid=netuid, + hotkey_ss58=hotkey_ss58, + wait_for_inclusion=True, + wait_for_finalization=False, + ) + print("Success" if success else f"Failed: {msg}") + +asyncio.run(main()) +``` + + + diff --git a/docs/miners/index.md b/docs/miners/index.md index 4840719d38..3d2035ae60 100644 --- a/docs/miners/index.md +++ b/docs/miners/index.md @@ -9,14 +9,14 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; ## Choosing a subnet -All mining in Bittensor occurs within a subnet. Each subnet independently produces the digital commodities that are its purpose, each subnet creator defining a different _incentive mechanism_ for validators to use in judging miners' work. It is validators scores of miners' performance, according to this incentive mechanism, that determines the proportion of the subnet's emissions allocated to each miner. See [Emissions](../emissions.md). +All mining in Bittensor occurs within a subnet. Each subnet independently produces the digital commodities that are its purpose. Each subnet creator defines a different _incentive mechanism_ for validators to use in judging miners' work. Its validators score miners' performances according to the subnet's incentive mechanism. These scores determine the proportion of the subnet's emissions allocated to each miner. See [Emissions](../learn/emissions.md). -Mining in Bittensor is not like mining Bitcoin or many other blockchains, it is active, creative, and competitive. Preparing to be a subnet miner involves researching the right subnet(s) for _you_ to mine, given your own expertise and access to hardware. +Mining in Bittensor differs significantly from mining Bitcoin or other blockchains. It is active, creative, and competitive. Preparing to be a subnet miner involves researching the right subnet(s) for _you_ to mine, given your own expertise and access to hardware. Browse the subnets and explore links to their code repositories on [TAO.app' subnets listings](https://tao.app). :::tip Typical compute requirements -Each subnet may have distinct hardware requirements, but this [minimum requirements template for subnet creators](https://github.com/opentensor/bittensor-subnet-template/blob/main/min_compute.yml) may give an idea of minimum memory, bandwidth and storage requirements for a typical subnet node. +Each subnet may have distinct hardware requirements, but this [subnet minimum requirements template](https://github.com/opentensor/bittensor-subnet-template/blob/main/min_compute.yml#L14) may give an idea of the minimum memory, bandwidth and storage requirements for miners in a typical subnet node. Mining is not supported on Windows. ::: @@ -26,10 +26,10 @@ Mining is not supported on Windows. To participate as a miner, you must first register a hotkey with the subnet in order to receive a UID on that subnet. :::tip No need to create a subnet to mine -You **do not** have to create a subnet to mine on the Bittensor network. Most miners work on established subnets. +You **do not** have to create a subnet to mine on the Bittensor network. Most miners work on already established subnets. ::: -Registration has a cost in TAO, which fluctuates dynamically based on time since last registration. When you secure a UID slot in a subnet on the main chain, this TAO is sunk cost. +Registration has a cost in TAO, which fluctuates dynamically based on the time since the last registration. When you secure a UID slot in a subnet on the main chain, this TAO is sunk cost and cannot be recovered. A subnet can have a maximum of 64 subnet validator UIDs and 192 subnet miner UIDs (256 total) in subnets other than Subnet 1. @@ -41,14 +41,14 @@ When you delegate your TAO to a subnet validator, you attach your delegated TAO A hotkey can hold multiple UIDs across **separate** subnets. However, within one subnet, each UID must have a unique hotkey. ::: -Run the following command on your terminal, replacing ``, ``, ``. +To register your keys with a subnet, run the following command on your terminal, replacing ``, ``, ``. `` is the `netuid` of your preferred subnet. ```bash btcli subnet register --netuid --wallet.name --wallet.hotkey ``` -For example, for subnet 1 (netuid of 1): +For example, to register your keys with subnet 1—netuid of 1: ```bash btcli subnet register --netuid 1 --wallet.name test-coldkey --wallet.hotkey test-hotkey @@ -56,7 +56,15 @@ btcli subnet register --netuid 1 --wallet.name test-coldkey --wallet.hotkey test ## Miner deregistration -Miners as well as validators can be deregistered if their emissions are low. +A miner can be deregistered if it earns low emissions due to receiving low weights (ratings) from validators. Typical subnets have 256 UID slots per subnet, of which a maximum of 64 subnet can be occupied by validators. Each tempo, the lowest ranked slot is deregistered from the hotkey that holds it and assigned to a new registrant. + +- Every subnet has an `immunity_period` hyperparameter expressed in a number of blocks. + :::tip See + See [`immunity_period`](../subnets/subnet-hyperparameters.md#immunityperiod). + ::: +- A subnet miner or validator at a UID (in that subnet) has a defined number of blocks to improve its performance. This is known as `immunity_period`. When the `immunity_period` expires, that miner or validator can be deregistered if it has the lowest performance in the subnet and a new registration arrives. +- A neuron's `immunity_period` starts when the miner or validator is registered into the subnet. + Validators as well as miners can be deregistered if their emissions are low; either role requires a UID. Typically, subnets have 256 UID slots, with a maximum of 64 slots capable of serving as validators by default. This leaves 192 UIDs for miners, though if there are fewer than 64 eligible validators on a subnet, miners can occupy available slots. @@ -64,7 +72,7 @@ Typically, subnets have 256 UID slots, with a maximum of 64 slots capable of ser Deregistration only occurs on subnets where all 256 UID slots are occupied. If a new registration occurs in a subnet with available UID slots, the registered neuron occupies one of the available UID slots. ::: -Each tempo, the '[neuron](../learn/bittensor-building-blocks)' (miner _or_ validator node) with the lowest 'pruning score' (based solely on emissions), and that is no longer within its [immunity period](../subnets/subnet-hyperparameters.md#immunityperiod), risks being replaced by a newly registered neuron, who takes over that UID. +Each tempo, the '[neuron](../learn/neurons)' (miner _or_ validator node) with the lowest 'pruning score' (based solely on emissions), and that is no longer within its [immunity period](../subnets/subnet-hyperparameters.md#immunityperiod), risks being replaced by a newly registered neuron, who takes over that UID. :::info Deregistration is based on emissions The subnet does not distinguish between miners and validators for the purpose of deregistration. The chain only looks at emissions (represented as 'pruning score'). Whenever a new registration occurs in the subnet, the neuron with the lowest emissions will get deregistered. @@ -76,6 +84,19 @@ Every subnet has an `immunity_period` hyperparameter expressed in a number of bl A subnet neuron (miner or validator) at a UID (in that subnet) has `immunity_period` blocks to improve its performance. When `immunity_period` expires, that miner or validator can be deregistered if it has the lowest performance in the subnet and a new registration arrives. +**Implementation Details:** + +Immunity status is calculated dynamically using the formula `is_immune = (current_block - registered_at) < immunity_period`, where: + +- `current_block` is the current blockchain block number +- `registered_at` is the block number when the neuron was registered +- `immunity_period` is the configured protection period for the subnet (default: 4096 blocks ≈ 13.7 hours) + +**Code References:** + +- [`subtensor/pallets/subtensor/src/utils/misc.rs:442-448`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/utils/misc.rs#L442-448) - Immunity status calculation +- [`subtensor/pallets/subtensor/src/subnets/registration.rs:409-485`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/registration.rs#L409-485) - Pruning algorithm with immunity priority + :::tip Special cases - In the unlikely event that all neurons are still immune, the one with the lowest "pruning score" will be deregistered by the next incoming registration. @@ -110,6 +131,12 @@ style={{width: 990}} Emissions may not always appear as a smooth curve. Emission might only update at the end of tempo periods, or subnet validators might do more frequent internal updates. For example, a validator might detect new miners and refresh every 100 blocks. ::: +## Auto Staking + +Miners can enable auto staking to automatically stake their mining income to a validator of their choice. This feature streamlines compound staking by eliminating the need for manual staking operations. + +See [Auto Staking for Miners](./autostaking.md) for detailed information on setting up and managing auto staking. + ## Moving a subnet miner to a different machine Once your subnet miner has begun mining, you can move it to a different machine, but proceed with caution. @@ -132,24 +159,24 @@ btcli wallet overview --netuid After providing your wallet name when prompted, you will see output such as: -| Parameter | Value | Description | -| :---------- | :----------------- | :-------------------------------------------------------------------------- | -| COLDKEY | my_coldkey | The name of the coldkey associated with your slot. | -| HOTKEY | my_first_hotkey | The name of the hotkey associated with your slot. | -| UID | 5 | The index of the uid out of available uids. | -| ACTIVE | True | The validator has set weights within the subnet's activity_cutoff | -| STAKE(τ) | 71.296 | The amount of stake in this wallet. | -| RANK | 0.0629 | This miner's absolute ranking according to validators on the network. | -| TRUST | 0.2629 | This miner's trust as a proportion of validators on the network. | -| CONSENSUS | 0.89 | This validator's aggregate consensus score. | -| INCENTIVE | 0.029 | This miner's incentive, TAO emission, is attained via mining. | -| DIVIDENDS | 0.001 | This validator's dividends, TAO emission, are attained via validating. | -| EMISSION | 29_340_153 | This miner's total emission in RAO (10^(-9) TAO) per block. | -| VTRUST | 0.96936 | This validator's trust score as a validator. | -| VPERMIT | \* | For validators: The uid is considered active for validating on this subnet. | -| UPDATED | 43 | Blocks since this miner set weights on the chain. | -| AXON | 131.186.56.85:8091 | The entrypoint advertised by this miner on the bittensor blockchain. | -| HOTKEY_SS58 | 5F4tQyWr... | The ss58-encoded address of the miner's hotkey. | +| Parameter | Example value | Description | +| :---------- | :----------------- | :------------------------------------------------------------------------------------- | +| COLDKEY | my_coldkey | The name of the coldkey associated with your slot. | +| HOTKEY | my_first_hotkey | The name of the hotkey associated with your slot. | +| UID | 5 | Unique identifier of the neuron. | +| ACTIVE | True | Whether or not the uid is considered active. | +| STAKE(τ) | 71.296 | The amount of stake in this wallet. | +| RANK | 0.0629 | This miner's absolute ranking according to validators on the network. | +| TRUST | 0.2629 | This miner's trust score as a proportion of validators on the network. | +| CONSENSUS | 0.89 | The consensus score of the neuron. | +| INCENTIVE | 0.029 | Thencentive score representing the miner's incentive alignment. | +| DIVIDENDS | 0.001 | The dividends earned by the neuron for validating on the subnet. | +| EMISSION | 29_340_153 | The emission in RAO (p) received by the neuron. | +| VTRUST | 0.96936 | The validator trust score indicating the network's trust in the neuron as a validator. | +| VPERMIT | \* | Whether this neuron is considered eligible for validating on this subnetwork. | +| UPDATED | 43 | Blocks since the neuron set weights on the chain. | +| AXON | 131.186.56.85:8091 | The entrypoint advertised by this miner on the bittensor blockchain. | +| HOTKEY_SS58 | 5F4tQyWr... | The ss58-encoded address of the miner's hotkey. | ## Checking miner registration status diff --git a/docs/miners/miners-btcli-guide.md b/docs/miners/miners-btcli-guide.md index f55f820400..322d98aa29 100644 --- a/docs/miners/miners-btcli-guide.md +++ b/docs/miners/miners-btcli-guide.md @@ -6,40 +6,40 @@ title: "Miner's Guide to `BTCLI`" This page discusses `btcli` security and usage considerations specifically for Bittensor miners. -For general coverage of `btcli` security and usage considerations across persona, see: [Bittensor CLI: Permissions Guide](../btcli-permissions) +For general coverage of `btcli` security and usage considerations across persona, see: [Bittensor CLI: Permissions Guide](../btcli/btcli-permissions) See also: -- [Wallets, Coldkeys and Hotkeys in Bittensor](../getting-started/wallets) for an introduction to the authentication technology used in Bittensor. -- [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security) for contrete security details about managing keys material. - +- [Wallets, Coldkeys and Hotkeys in Bittensor](../keys/wallets) for an introduction to the authentication technology used in Bittensor. +- [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security) for contrete security details about managing keys material. ## Intro -Miners in Bittensor work to produce digital commondities. To securely serve these commodities to validators, miners use their registered hotkey to sign requests. Therefore, miners primarily rely on **hotkeys** for daily operations. +Miners in Bittensor work to produce digital commodities. To securely serve these commodities to validators, miners use their registered hotkey to sign requests. Therefore, miners primarily rely on **hotkeys** for daily operations. The **coldkey** is only needed when you need to create or fund that hotkey, or if you want to stake additional TAO or pay the burn for registrations. - Miners must also manage their own TAO and alpha stake (to exit the emissions that accure to them), and hence should familiarize themselves with staking operations. See: + - [Staking/Delegation Overview](../staking-and-delegation/delegation) - [Staker's Guide to `BTCLI`](../staking-and-delegation/stakers-btcli-guide) +Creating hotkeys requires a coldkey private key, and should be done on a secure [coldkey workstation](../keys/coldkey-hotkey-security#coldkey-workstation). However, using hotkeys for signing requests when mining does not require a coldkey, which should never be present on a mining server, i.e. a hotkey workstation. The coldkey should not be placed on a machine used for mining because the software dependencies for mining should not be considered safe/trusted code to the standards of a coldkey workstation. -Creating hotkeys requires a coldkey private key, and should be done on a secure [coldkey workstation](../getting-started/coldkey-hotkey-security#coldkey-workstation). However, using hotkeys for signing requests when mining does not require a coldkey, which should never be present on a mining server, i.e. a hotkey workstation. The coldkey should not be placed on a machine used for mining because the software dependencies for mining should not be considered safe/trusted code to the standards of a coldkey workstation. - -See [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security). +See [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security). ## Requirements for mining functions ### Unpermissioned workstation (public keys only): + - Check balances - Monitor emissions and other metagraph info - Check subnet alpha prices across Bittensor ### Coldkey workstation: + - Create/import coldkey - Create hotkeys - Manage TAO and alpha stake @@ -48,6 +48,7 @@ See [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey- - Register a hotkey to mine on a subnet ### Mining node (Hotkey workstation): + - Import/provision hotkey - Provide hotkey to subnet codebase for operations such as axon serving, commitment creation etc @@ -56,18 +57,16 @@ See [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey- Miners will need coldkeys to manage their TAO and alpha currency, as well as hotkeys to serve requests. Ensure there is a clear boundary: The coldkey should **never** be on an environment with untrusted ML code from containers, frameworks, or libraries that might exfiltrate secrets. ::: -## `btcli` commandsfor miners: +## `btcli` commands for miners: -### Hotkey Managementd +### Hotkey Management -`btcli wallet new-hotkey` , `btcli wallet regen-hotkey`, : Create and register a hotkey on a secure coldkey workstation then transfer the hotkey file or mnemonic to the mining workstation. +`btcli wallet new-hotkey` , `btcli wallet regen-hotkey`, : Create and register a hotkey on a secure coldkey workstation then transfer the hotkey file or mnemonic to the mining workstation. `btcli subnets register`, `btcli subnets pow-register`: register a UID - ## Key rotation If you suspect your coldkey may have been leaked, you can request to swap it out of your wallet, using an extrinsic blockchain transaction. This operation has a 5 day waiting period, during which your coldkey will be locked. The cost of this coldkey swap transaction is 0.1 TAO. -See [Rotate/Swap your Coldkey](../subnets/schedule-coldkey-swap) - +See [Rotate/Swap your Coldkey](../keys/schedule-coldkey-swap) diff --git a/docs/_components.md b/docs/misc/_components.md similarity index 100% rename from docs/_components.md rename to docs/misc/_components.md diff --git a/docs/_sphinx-gen.md b/docs/misc/_sphinx-gen.md similarity index 71% rename from docs/_sphinx-gen.md rename to docs/misc/_sphinx-gen.md index 2390647b9e..27b6ec1f35 100644 --- a/docs/_sphinx-gen.md +++ b/docs/misc/_sphinx-gen.md @@ -2,7 +2,7 @@ Building and Publishing Bittensor Python Reference Docs with Sphinx Install virtual env python3 -m venv sphinx_venv -source sphinx_venv/bin/activate +source sphinx_venv/bin/activate Install Sphinx and the required extensions @@ -11,27 +11,26 @@ Do a "tar xvf sphinx-starter.tar" in a new directory. This will extract three fi Run "pip install -r requirements.txt". This will install Sphinx and the required extensions. Build docs locally -In the "source/conf.py" file, change line 67 (autoapi_dirs = ["/Users/rajkaramchedu/2scratch/bittensor/bittensor"]) and put in the path to your local Bittensor clone repo. -Also on line 28 of “source/conf.py”, put in your path for Python site-packages. -Run "make html". This will create a "build" directory and place reference html docs in it. -Open the docs with the command: open build/html/index.html and you will see all the reference docs, exactly like how the published version looks like, including CSS customizations. -When you edit a docstring in the Bittensor repo, run this command to delete old stuff and rebuild html: rm -r build && make html This will make sure the "build" directory is removed before rebuilding the docs, or else it will use the old stuff in the "build" directory, and we don't want that. -In the “source” directory, there are separate “index.rst” files for Wallet SDK, Bittensor SDK and for legacy docs. If you are generating Wallet API docs, then copy over the “index.rst.btwallet” into “index.rst” before you build the docs. +In the "source/conf.py" file, change line 67 (autoapi_dirs = ["/Users/rajkaramchedu/2scratch/bittensor/bittensor"]) and put in the path to your local Bittensor clone repo. +Also on line 28 of “source/conf.py”, put in your path for Python site-packages. +Run "make html". This will create a "build" directory and place reference html docs in it. +Open the docs with the command: open build/html/index.html and you will see all the reference docs, exactly like how the published version looks like, including CSS customizations. +When you edit a docstring in the Bittensor repo, run this command to delete old stuff and rebuild html: rm -r build && make html This will make sure the "build" directory is removed before rebuilding the docs, or else it will use the old stuff in the "build" directory, and we don't want that. +In the “source” directory, there are separate “index.rst” files for Wallet SDK, Bittensor SDK and for legacy docs. If you are generating Wallet API docs, then copy over the “index.rst.btwallet” into “index.rst” before you build the docs. When you are ready to publish the docs, proceed to the below next step. Publish the docs -To publish the docs on docs.bittensor.com, you will push the entire "build/html" directory into the docs repo. However, before you do that, remove the `html/_sources` directory. This directory contains reStructuredText source files and we don't want to version control them. So, do rm -r build/html/_sources first. -In the docs repo, https://github.com/opentensor/developer-docs/tree/main , this "html" directory is located in the "developer-docs/python-api" path. Always replace the entire "html" directory even if you updated a single word or letter in a docstring. -In the Markdown file that contains links to these Python reference docs and sections, you will use "pathname:///python-api/html/index.html" for linking to the homepage of the Python ref docs. See "docs/bt-api-ref.md" for examples. +To publish the docs on docs.bittensor.com, you will push the entire "build/html" directory into the docs repo. However, before you do that, remove the `html/_sources` directory. This directory contains reStructuredText source files and we don't want to version control them. So, do rm -r build/html/\_sources first. +In the docs repo, https://github.com/latent-to/developer-docs/tree/main , this "html" directory is located in the "developer-docs/python-api" path. Always replace the entire "html" directory even if you updated a single word or letter in a docstring. +In the Markdown file that contains links to these Python reference docs and sections, you will use "pathname:///python-api/html/index.html" for linking to the homepage of the Python ref docs. See "docs/bt-api-ref.md" for examples. Conf.py -The "source/conf.py" is where all the configuration for docs generation is defined. -See Sphinx website here: https://www.sphinx-doc.org/en/master/index.html -We use Sphinx AutoAPI extension for docstrings to html generation. See the docs for the extension here: https://sphinx-autoapi.readthedocs.io/en/latest/reference/config.html -We use Sphinx Book Theme with additional custom CSS tweaks. Our custom CSS file is located in the `source/_static` directory. The Sphinx Book Theme docs are in https://sphinx-book-theme.readthedocs.io/en/stable/tutorials/get-started.html -Finally, we use Google style for docstrings. See the description here: https://github.com/opentensor/developer-docs/blob/main/WRITING-STYLE-GUIDE.md#python-docstrings +The "source/conf.py" is where all the configuration for docs generation is defined. +See Sphinx website here: https://www.sphinx-doc.org/en/master/index.html +We use Sphinx AutoAPI extension for docstrings to html generation. See the docs for the extension here: https://sphinx-autoapi.readthedocs.io/en/latest/reference/config.html +We use Sphinx Book Theme with additional custom CSS tweaks. Our custom CSS file is located in the `source/_static` directory. The Sphinx Book Theme docs are in https://sphinx-book-theme.readthedocs.io/en/stable/tutorials/get-started.html +Finally, we use Google style for docstrings. See the description here: https://github.com/latent-to/developer-docs/blob/main/WRITING-STYLE-GUIDE.md#python-docstrings That's it. Happy documenting. - diff --git a/docs/navigating-subtensor/emissions-coinbase.md b/docs/navigating-subtensor/emissions-coinbase.md new file mode 100644 index 0000000000..8feb443108 --- /dev/null +++ b/docs/navigating-subtensor/emissions-coinbase.md @@ -0,0 +1,307 @@ +--- +title: "Coinbase Implementation" +--- + +# Coinbase Implementation + +This document provides a technical deep dive into the `run_coinbase()` function that orchestrates [TAO](../resources/glossary.md#tao-τ) and alpha [emission](../resources/glossary.md#emission) distribution across [subnets](../resources/glossary.md#subnet). The coinbase mechanism serves as Bittensor's economic heartbeat, connecting [subnet validators](../resources/glossary.md#validator), [subnet miners](../resources/glossary.md#subnet-miner), and [stakers](../resources/glossary.md#staking) through emission distribution. + +For conceptual understanding of emission mechanisms, see [Emissions](../learn/emissions.md). + +The coinbase mechanism orchestrates Bittensor's tokenomic engine, running every 12-second [block](../resources/glossary.md#block) to ensure continuous flow of liquidity into the network. + +Every block, the coinbase mechanism performs three critical functions: + +1. **Liquidity Injection**: Adds TAO and subnet-specific alpha tokens to each subnet's liquidity pools. +2. **Accumulation**: Builds up pending [emissions](../resources/glossary.md#emission) (also known as "alpha outstanding") bound for distribution to [subnet miners](../resources/glossary.md#subnet-miner) and [validators](../resources/glossary.md#validator) during the next [epoch](../resources/glossary.md#tempo). +3. **Consensus Triggering**: Initiates each subnet's [Yuma Consensus](../resources/glossary.md#yuma-consensus) epochs, the process that distributes emissions to participants within each subnet. Epochs are staggered to avoid overloading the blockchain with the computation involved. + +For broader conceptual understanding of emission mechanisms, see [Emissions](../learn/emissions.md). + +## Core Function: `run_coinbase()` + +**Location**: [`run_coinbase.rs`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/coinbase/run_coinbase.rs) + +```rust +pub fn run_coinbase(block_emission: U96F32) +``` + +**Parameters**: +- `block_emission`: Total TAO to distribute across all subnets this block. Currently 1 $\tau$, this amount will follow a halving schedule. + +The function implements a multistep process that handles liquidity injection, reward accumulation, epoch triggering, and EMA updates. + +## Implementation Flow + +### 1. Subnet Discovery and Filtering + +The process begins with identifying subnets eligible for emissions, applying filters to ensure only active, established subnets participate in the reward distribution. + +```rust +// Get all netuids (filter out root) +let subnets: Vec = Self::get_all_subnet_netuids() + .into_iter() + .filter(|netuid| *netuid != NetUid::ROOT) + .collect(); + +// Filter out subnets with no first emission block number +let subnets_to_emit_to: Vec = subnets + .clone() + .into_iter() + .filter(|netuid| FirstEmissionBlockNumber::::get(*netuid).is_some()) + .collect(); +``` + +**Subnet Eligibility Rules:** +- **[Root Subnet](../resources/glossary.md#root-subnetsubnet-zero) Exclusion**: [Subnet Zero](../resources/glossary.md#root-subnetsubnet-zero) operates differently—it has no [subnet miners](../resources/glossary.md#subnet-miner) and serves as a TAO staking pool for [delegates](../resources/glossary.md#delegate), so it's excluded from direct alpha emissions +- **Emission Readiness**: Only subnets that have been started (and hence been assigned a `FirstEmissionBlockNumber`) receive emissions. +### 2. Emission Allocation to Subnets + +Each subnet's share of the block's TAO emission depends on its alpha token's price, smoothed with an [exponential moving average (EMA)](../learn/ema) function to prevent price manipulation while maintaining market responsiveness. + +```rust +let mut total_moving_prices = U96F32::saturating_from_num(0.0); +for netuid_i in subnets_to_emit_to.iter() { + total_moving_prices = total_moving_prices + .saturating_add(Self::get_moving_alpha_price(*netuid_i)); +} +``` + +**EMA Price Smoothing Implementation:** +The moving price for each subnet is calculated using a custom [EMA](../learn/ema) that adapts its responsiveness based on subnet maturity. This creates a **double-smoothing effect**: new subnets have extremely slow price adaptation (preventing launch manipulation), while mature subnets respond more quickly to legitimate market signals. + +**Price-Driven Distribution:** +Each subnet receives TAO emissions proportional to its EMA-smoothed alpha token price: + +$$ +\text{tao\_allocation}_i = \text{block\_emission} \times \frac{\text{moving\_price}_i}{\sum_{j} \text{moving\_price}_j} +$$ + +**EMA Update Timing:** The EMA is updated **after** being used for emission calculations in each `run_coinbase()` call ([Line 246](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/coinbase/run_coinbase.rs#L246)), ensuring that current block emissions are based on the previous block's smoothed prices while continuously updating the moving average for future calculations. + +### 3. Token Pool Injections and Emissions + +For each subnet, the coinbase calculates critical values that govern the subnet's token economics and determine how fresh liquidity flows into the system. + +#### TAO In (`tao_in`): Fresh Liquidity Injection +- Represents new TAO flowing into the subnet's liquidity pool +- Calculated from the subnet's proportional share of block emissions +- May be reduced through the subsidy mechanism to maintain price stability + +#### Alpha In (`alpha_in`): Liquidity Pool Balance +- Alpha tokens injected to maintain healthy AMM pool ratios +- Ensures the TAO injection doesn't create excessive [slippage](../resources/glossary.md#slippage) for [stakers](../resources/glossary.md#staking) +- Calculated as: `tao_in / current_price` during normal operations + +#### Alpha Out (`alpha_out`): Participant Emissions +- Alpha tokens emitted for distribution to [miners](../resources/glossary.md#subnet-miner) and [subnet validators](../resources/glossary.md#validator) +- Represents the subnet's emission budget for [incentives](../resources/glossary.md#incentives) and validator dividends +- Forms the reward pool that will be processed during [epochs](../resources/glossary.md#tempo) + +#### Subsidy Mechanism + +When a subnet's alpha price falls below its expected emission proportion, the mechanism automatically intervenes to maintain market stability: +1. **Price Neutral Injection**: Downscales both TAO and ALPHA injected to provide a price neutral injection +2. **Market Making**: Uses the excess TAO for buying pressure on alpha tokens + +This encourages alpha prices to move towards their emission ratio, or to encourage the sum of prices to be at/above 1. + +```rust +for netuid_i in subnets_to_emit_to.iter() { + let price_i = T::SwapInterface::current_alpha_price((*netuid_i).into()); + let moving_price_i: U96F32 = Self::get_moving_alpha_price(*netuid_i); + + let default_tao_in_i: U96F32 = block_emission + .saturating_mul(moving_price_i) + .checked_div(total_moving_prices) + .unwrap_or(asfloat!(0.0)); + + let alpha_emission_i: U96F32 = asfloat!( + Self::get_block_emission_for_issuance( + Self::get_alpha_issuance(*netuid_i).into() + ).unwrap_or(0) + ); + + + let tao_in_ratio: U96F32 = default_tao_in_i.safe_div_or( + U96F32::saturating_from_num(block_emission), + U96F32::saturating_from_num(0.0), + ); + + if price_i < tao_in_ratio { + tao_in_i = price_i.saturating_mul(block_emission); + alpha_in_i = block_emission; + let difference_tao: U96F32 = default_tao_in_i.saturating_sub(tao_in_i); + + let buy_swap_result = Self::swap_tao_for_alpha( + *netuid_i, + tou64!(difference_tao).into(), + T::SwapInterface::max_price().into(), + true, // skip fees + ); + } else { + // Normal operation + tao_in_i = default_tao_in_i; + alpha_in_i = tao_in_i.safe_div_or(price_i, alpha_emission_i); + } +} +``` + +### 4. Liquidity Pool Updates + +The coinbase updates each subnet's liquidity pools. + + +**Critical State Updates:** +- **`SubnetAlphaIn`**: Alpha reserves backing the AMM, enabling liquid [staking](../resources/glossary.md#staking) and unstaking operations. +- **`SubnetAlphaOut`**: Accumulated emissions and/or ALPHA outside the pool (ALPHA emissions + ALPHA taken out from pool). +- **`SubnetTAO`**: TAO reserves backing the AMM, providing price stability and liquidity for unstaking. +- **`TotalIssuance`**: Global TAO supply (see [Issuance](../resources/glossary.md#issuance)). + +```rust +for netuid_i in subnets_to_emit_to.iter() { + // Inject Alpha in (AMM liquidity) + let alpha_in_i = AlphaCurrency::from( + tou64!(*alpha_in.get(netuid_i).unwrap_or(&asfloat!(0))) + ); + SubnetAlphaIn::::mutate(*netuid_i, |total| { + *total = total.saturating_add(alpha_in_i); + }); + + // Inject Alpha outstanding + let alpha_out_i = AlphaCurrency::from( + tou64!(*alpha_out.get(netuid_i).unwrap_or(&asfloat!(0))) + ); + SubnetAlphaOut::::mutate(*netuid_i, |total| { + *total = total.saturating_add(alpha_out_i); + }); + + // Inject TAO in (AMM liquidity) + let tao_in_i: TaoCurrency = + tou64!(*tao_in.get(netuid_i).unwrap_or(&asfloat!(0))).into(); + SubnetTAO::::mutate(*netuid_i, |total| { + *total = total.saturating_add(tao_in_i.into()); + }); + + // Update global TAO supply tracking + TotalIssuance::::mutate(|total| { + *total = total.saturating_add(tao_in_i.into()); + }); + + // Notify AMM of new liquidity + T::SwapInterface::adjust_protocol_liquidity(*netuid_i, tao_in_i, alpha_in_i); +} +``` + +### 5. Subnet Owner Emissions + +Before distributing rewards to [miners](../resources/glossary.md#subnet-miner) and [subnet validators](../resources/glossary.md#validator), the system allocates a percentage to [subnet owners](../resources/glossary.md#subnet-creator). + +[Subnet owners](../resources/glossary.md#subnet-creator) receive 18% of alpha emissions. The subnet owner cut is calculated before other distributions so that the owner cut can be passed to `drain_pending_emission` (there was a bug before where the owner cut was incorrectly calculated after). Subnet owner emissions accumulate in `PendingOwnerCut` until the next [epoch](../resources/glossary.md#tempo). + + +```rust +let cut_percent: U96F32 = Self::get_float_subnet_owner_cut(); // Default: ~18% +let mut owner_cuts: BTreeMap = BTreeMap::new(); + +for netuid_i in subnets_to_emit_to.iter() { + let alpha_out_i: U96F32 = *alpha_out.get(netuid_i).unwrap_or(&asfloat!(0)); + let owner_cut_i: U96F32 = alpha_out_i.saturating_mul(cut_percent); + + owner_cuts.insert(*netuid_i, owner_cut_i); + alpha_out.insert(*netuid_i, alpha_out_i.saturating_sub(owner_cut_i)); + + PendingOwnerCut::::mutate(*netuid_i, |total| { + *total = total.saturating_add(tou64!(owner_cut_i).into()); + }); +} +``` + + +### 6. Calculating Root Proportion + +The root proportion on each subnet determines how much of the dividends (41% of ALPHA emissions) are being sold for each block and being distributed to stakers on root. + +$$ +\text{root\_proportion} = \frac{\text{root\_tao} \times \text{tao\_weight}}{\text{root\_tao} \times \text{tao\_weight} + \text{alpha\_issuance}} +$$ + +Where: +- `root_tao`: Total TAO [staked](../resources/glossary.md#staking) in [Root Subnet](../resources/glossary.md#root-subnetsubnet-zero) +- `tao_weight`: Global parameter ([TAO Weight](../resources/glossary.md#tao-weight)) determining TAO vs alpha influence +- `alpha_issuance`: Total alpha tokens for this specific subnet + + +```rust +for netuid_i in subnets_to_emit_to.iter() { + let alpha_out_i: U96F32 = *alpha_out.get(netuid_i).unwrap_or(&asfloat!(0.0)); + let root_tao: U96F32 = asfloat!(SubnetTAO::::get(NetUid::ROOT)); + let alpha_issuance: U96F32 = asfloat!(Self::get_alpha_issuance(*netuid_i)); + let tao_weight: U96F32 = root_tao.saturating_mul(Self::get_tao_weight()); + + // Calculate root subnet's proportional share + let root_proportion: U96F32 = tao_weight + .checked_div(tao_weight.saturating_add(alpha_issuance)) + .unwrap_or(asfloat!(0.0)); + + // 50% of proportional alpha goes to root validators + let root_alpha: U96F32 = root_proportion + .saturating_mul(alpha_out_i) + .saturating_mul(asfloat!(0.5)); + + let pending_alpha: U96F32 = alpha_out_i.saturating_sub(root_alpha); + + // Convert root alpha to TAO through AMM (if not subsidized) + // If the subnet is subsidized by the Subsidy Mechanism then no ALPHA will be sold - so the dividends for root are stopped. + if !subsidized { + let swap_result = Self::swap_alpha_for_tao( + *netuid_i, + tou64!(root_alpha).into(), + T::SwapInterface::min_price().into(), + true, // skip fees + ); + + if let Ok(ok_result) = swap_result { + PendingRootDivs::::mutate(*netuid_i, |total| { + *total = total.saturating_add(ok_result.amount_paid_out.into()); + }); + } + } + + PendingEmission::::mutate(*netuid_i, |total| { + *total = total.saturating_add(tou64!(pending_alpha).into()); + }); +} +``` + + +### 7. Epoch Execution + +When each subnet's [tempo](../resources/glossary.md#tempo) interval completes, the coinbase triggers execution of its Yuma Consensus *epoch*. Epochs execute when `(block_number + netuid + 1) % (tempo + 1) == 0`, creating a predictable, staggered schedule of epoch execution. + +The coinbase passes accumulated emissions to `drain_pending_emission()`, which executes the [full Yuma Consensus algorithm](./epoch.md) including validator weight processing, consensus calculation, bond updates, and final emission distribution to participants. + +For detailed implementation of the consensus mechanism, validator weight processing, and emission distribution, see [Epoch Implementation](./epoch.md). + +```rust +for &netuid in subnets.iter() { + // Process matured commit-reveal weight submissions + if let Err(e) = Self::reveal_crv3_commits(netuid) { + log::warn!("Failed to reveal commits for subnet {netuid} due to error: {e:?}"); + } + + if Self::should_run_epoch(netuid, current_block) { + // Reset epoch timing and collect accumulated emissions + BlocksSinceLastStep::::insert(netuid, 0); + LastMechansimStepBlock::::insert(netuid, current_block); + + // Execute Yuma Consensus with accumulated rewards + Self::drain_pending_emission(netuid, pending_alpha, pending_tao, pending_swapped, owner_cut); + } else { + BlocksSinceLastStep::::mutate(netuid, |total| *total = total.saturating_add(1)); + } +} +``` + + + diff --git a/docs/navigating-subtensor/epoch.md b/docs/navigating-subtensor/epoch.md new file mode 100644 index 0000000000..bddd87142f --- /dev/null +++ b/docs/navigating-subtensor/epoch.md @@ -0,0 +1,554 @@ +--- +title: "Implementation of the Yuma Consensus Epoch" +--- + +# Implementation of the Yuma Consensus Epoch + +If [Yuma Consensus (YC](../resources/glossary.md#yuma-consensus) is the heart of Bittensor, the epoch is the heartbeat, a regular pulse of calculations that processes [validator](../resources/glossary.md#validator) weights and determines [emissions](../resources/glossary.md#emission) for participants. This page takes a deep dive into how the code accomplishes its purpose. + +The epoch function takes as its input the matrix of values assigned to each miner by each validator, and returns emission tuples of hotkey, emission for mining, and emission for validating. + +It derives these by performing stake-weighted consensus (YC) over them in order to derive the aggregated miner ratings and miner-validator bonds. Miners gain emissions (incentives) based on their aggregate ratings, and validators gain emissions (dividends) based on their bonds to highly rated miners. + +The basic flow of the epoch is: + +1. Validator weights are submitted during the preceding [tempo](../resources/glossary.md#tempo). +2. [Stake weight](../resources/glossary.md#stake-weight) determines validator influence during consensus. +3. [Consensus](../resources/glossary.md#consensus-score) computation clips validator-miner ratings that outlie the stake-weighted median. +4. Bonds update via [exponential moving averages](../resources/glossary.md#exponential-moving-average-ema). +5. Emissions are allocated to miners and validators. + + +## Core Function: `epoch()` + +Source code: [`run_epoch.rs`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs). + +### Function Signature +```rust +pub fn epoch( + netuid: NetUid, + rao_emission: AlphaCurrency, +) -> Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)> +``` + +## Implementation Flow + +### 1. Network State Collection + +```rust +// Get subnetwork size +let n = Self::get_subnetwork_n(netuid); + +// Get current block and timing +let current_block: u64 = Self::get_current_block_as_u64(); +let tempo: u64 = Self::get_tempo(netuid).into(); +let activity_cutoff: u64 = Self::get_activity_cutoff(netuid) as u64; + +// Get neuron activity data +let last_update: Vec = Self::get_last_update(netuid); +let block_at_registration: Vec = Self::get_block_at_registration(netuid); + +// Calculate inactive neurons +let inactive: Vec = last_update + .iter() + .map(|updated| updated.saturating_add(activity_cutoff) < current_block) + .collect(); + +let active: Vec = inactive.iter().map(|&b| !b).collect(); +``` + +**Activity Determination:** +A [neuron](../resources/glossary.md#neuron) is considered inactive if: +``` +last_update + activity_cutoff < current_block +``` + +This ensures only recently active participants influence consensus. + +### 2. Stake Processing and Validation + +First, get hotkeys mapped to stake-weights. + +```rust + +let hotkeys: Vec<(u16, T::AccountId)> = + as IterableStorageDoubleMap>::iter_prefix(netuid) + .collect(); + +let (total_stake, _alpha_stake, _tao_stake): (Vec, Vec, Vec) = + Self::get_stake_weights_for_network(netuid); + +let min_stake = Self::get_stake_threshold(); +``` + +Filter out hotkeys below minimum stake threshold. +```rust +let mut filtered_stake: Vec = total_stake + .iter() + .map(|&s| { + if fixed64_to_u64(s) < min_stake { + return I64F64::from(0); + } + s + }) + .collect(); + +// Normalize stake +inplace_normalize_64(&mut filtered_stake); +let stake: Vec = vec_fixed64_to_fixed32(filtered_stake); +``` + +:::info Stake-Weight Calculation +**Stake-Weight** = alpha_stake + (tao_stake × tao_weight) + +The `get_stake_weights_for_network()` function combines: +- **Alpha stake**: Subnet-specific token holdings +- **TAO stake**: [Root subnet](../resources/glossary.md#root-subnetsubnet-zero) holdings weighted by `[tao_weight](../resources/glossary.md#tao-weight)` (default: 18%) +::: + + +Filter validator permit candidates for minimum stake-weight. + +```rust +// Get the minimum stake required +let min_stake = Self::get_stake_threshold(); + +let mut filtered_stake: Vec = total_stake + .iter() + .map(|&s| { + if fixed64_to_u64(s) < min_stake { + return I64F64::from(0); + } + s + }) + .collect(); +``` + + +### 3. Validator Permit Management + +Validator permits are dynamically calculated every epoch based on stake distribution. This system ensures that only the most committed (highest-staked) participants can influence consensus. + +```rust +// Get current validator permits +let validator_permits: Vec = Self::get_validator_permit(netuid); +let validator_forbids: Vec = validator_permits.iter().map(|&b| !b).collect(); + +// Get max allowed validators +let max_allowed_validators: u16 = Self::get_max_allowed_validators(netuid); + +// Calculate new validator permits based on top-k stake +let new_validator_permits: Vec = + is_topk_nonzero(&stake, max_allowed_validators as usize); +``` + +**Validator Selection Algorithm:** + +The `is_topk_nonzero()` function implements a filtering process: + +1. **Stake Filtering**: Only neurons with stake ≥ `stake_threshold` (minimum 1000 stake weight) are considered +2. **Top-K Selection**: The top K neurons by stake weight receive validator permits (default: top 64) +3. **Non-Zero Requirement**: Neurons with zero stake are automatically excluded +4. **Stable Sorting**: Uses ascending stable sort to ensure deterministic selection when stakes are equal + +**Algorithm Details:** +```rust +pub fn is_topk_nonzero(vector: &[I32F32], k: usize) -> Vec { + let n: usize = vector.len(); + let mut result: Vec = vector.iter().map(|&elem| elem != I32F32::from(0)).collect(); + if n < k { + return result; // All non-zero elements get permits if total < k + } + let mut idxs: Vec = (0..n).collect(); + idxs.sort_by_key(|&idx| &vector[idx]); // ascending stable sort + for &idx in idxs.iter().take(n.saturating_sub(k)) { + result[idx] = false; // Mark bottom (n-k) elements as false + } + result +} +``` + +This ensures that exactly K neurons (or fewer if insufficient candidates) receive validator permits, with deterministic tie-breaking through stable sorting. + +**Permit Lifecycle:** + +```rust +// Bonds are cleared when permits are lost +new_validator_permits + .iter() + .zip(validator_permits) + .zip(ema_bonds) + .enumerate() + .for_each(|(i, ((new_permit, validator_permit), ema_bond))| { + if *new_permit { + // Retain bonds if permit is maintained + let new_bonds_row: Vec<(u16, u16)> = ema_bond + .iter() + .map(|(j, value)| (*j, fixed_proportion_to_u16(*value))) + .collect(); + Bonds::::insert(netuid, i as u16, new_bonds_row); + } else if validator_permit { + // Clear bonds if permit is lost + let new_empty_bonds_row: Vec<(u16, u16)> = vec![]; + Bonds::::insert(netuid, i as u16, new_empty_bonds_row); + } + }); +``` + +**Key Features:** +- **Dynamic Updates**: Permits are recalculated every epoch based on current stake distribution +- **Bond Preservation**: Neurons retain their bonds only while holding validator permits +- **Automatic Cleanup**: Bonds are cleared when permits are lost, preventing stale relationships +- **Stake Threshold**: Minimum stake requirement (typically 1000 stake weight) filters out low-commitment participants + +**Related Documentation:** +- For validator setup and requirements, see [Validating in Bittensor](../validators/index.md) +- For detailed permit lifecycle management, see [Validator Permits section](../validators/index.md#validator-permits) + +**Code References:** +- Validator permit calculation: [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:520-537`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L520-537) +- Top-K selection algorithm: [`subtensor/pallets/subtensor/src/epoch/math.rs:250-263`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/math.rs#L250-263) +- Bond cleanup logic: [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:903-921`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L903-921) + +### 4. Active Stake Calculation + +```rust +let mut active_stake: Vec = stake.clone(); + +// Remove inactive stake +inplace_mask_vector(&inactive, &mut active_stake); + +// Remove non-validator stake +inplace_mask_vector(&validator_forbids, &mut active_stake); + +// Normalize active stake +inplace_normalize(&mut active_stake); +``` + +**Active stake** represents the consensus power of validators who are: +1. Recently active (within `activity_cutoff`) +2. Hold validator permits +3. Meet minimum stake requirements + +### 5. Weight Processing + +```rust +// Access network weights (sparse format) +let mut weights: Vec> = Self::get_weights_sparse(netuid); + +// Mask weights from non-permitted validators +weights = mask_rows_sparse(&validator_forbids, &weights); + +// Remove self-weights (except subnet owner if exists) +let owner_uid: Option = Self::get_owner_uid(netuid); +if let Some(owner_uid) = owner_uid { + weights = mask_diag_sparse_except_index(&weights, owner_uid); +} else { + weights = mask_diag_sparse(&weights); +} + +// Remove weights to deregistered neurons +weights = vec_mask_sparse_matrix( + &weights, + &last_update, + &block_at_registration, + &|updated, registered| updated <= registered, +); +``` + +**Weight Filtering:** +Weights are filtered to remove: +- **Self-weights**: Prevent validators from voting for themselves (except [subnet creator](../resources/glossary.md#subnet-creator)) +- **Outdated weights**: Weights set before target neuron's latest registration +- **Non-validator weights**: Only permitted validators can influence consensus + +#### Commit-Reveal Weight Processing + +```rust +if Self::get_commit_reveal_weights_enabled(netuid) { + let mut commit_blocks: Vec = vec![u64::MAX; n as usize]; + + // Process v2 commits + for (who, q) in WeightCommits::::iter_prefix(netuid) { + for (_, cb, _, _) in q.iter() { + if !Self::is_commit_expired(netuid, *cb) { + if let Some(i) = uid_of(&who) { + commit_blocks[i] = commit_blocks[i].min(*cb); + } + break; + } + } + } + + // Process v3 commits + for (_epoch, q) in CRV3WeightCommitsV2::::iter_prefix(netuid) { + for (who, cb, ..) in q.iter() { + if !Self::is_commit_expired(netuid, *cb) { + if let Some(i) = uid_of(who) { + commit_blocks[i] = commit_blocks[i].min(*cb); + } + } + } + } + + // Mask weights from validators with active commits + weights = vec_mask_sparse_matrix( + &weights, + &commit_blocks, + &block_at_registration, + &|cb, reg| cb < reg, + ); +} +``` + +**[Commit Reveal](../resources/glossary.md#commit-reveal) Logic:** +When enabled, validators must commit to weights before revealing them. Weights are masked if: +- Validator has an active (non-expired) commit +- Commit was made before target neuron's registration + +### 6. Weight Normalization + +```rust +// Normalize remaining weights by row +inplace_row_normalize_sparse(&mut weights); +``` + +After filtering, each validator's weights are normalized so they sum to 1.0, ensuring equal influence regardless of absolute weight values. + +### 7. Consensus Calculation + +```rust +// Compute preranks (before consensus clipping) +let preranks: Vec = matmul_sparse(&weights, &active_stake, n); + +// Get consensus threshold (default: 51%) +let kappa: I32F32 = Self::get_float_kappa(netuid); + +// Calculate consensus as stake-weighted median +let consensus: Vec = weighted_median_col_sparse(&active_stake, &weights, n, kappa); + +// Clip weights at consensus level +let clipped_weights: Vec> = col_clip_sparse(&weights, &consensus); +``` + +**Consensus Computation:** +For each miner j, consensus $\overline{W_j}$ is the maximum weight level supported by at least fraction κ of total stake: + +$$ +\overline{W_j} = \arg \max_{w} \left( \sum_{i \in \mathbb{V}} S_i \cdot \mathbf{1}_{W_{ij} \geq w} \geq \kappa \right) +$$ + +**Weight Clipping:** +Any weight above consensus is clipped: $\overline{W_{ij}} = \min(W_{ij}, \overline{W_j})$ + +### 8. Trust and Rank Calculation + +```rust +// Calculate validator trust (sum of clipped weights) +let validator_trust: Vec = row_sum_sparse(&clipped_weights); + +// Compute final ranks using clipped weights +let mut ranks: Vec = matmul_sparse(&clipped_weights, &active_stake, n); + +// Compute server trust (rank after / rank before clipping) +let trust: Vec = vecdiv(&ranks, &preranks); + +// Normalize ranks to get incentives +inplace_normalize(&mut ranks); +let incentive: Vec = ranks.clone(); +``` + +**[Trust](../resources/glossary.md#trust) Calculation:** +- **[Validator trust](../resources/glossary.md#validator-trust)**: Sum of a validator's clipped weights (measures alignment with consensus) +- **Server trust**: Ratio of post-clip to pre-clip [rank](../resources/glossary.md#rank) (measures consensus adherence) + +**Rank → [Incentive](../resources/glossary.md#incentives):** +Final normalized ranks become miner incentives, ensuring total incentives sum to 1.0. + +### 9. Bond Processing + +The bond mechanism depends on whether Yuma3 is enabled: + +#### Yuma3 Bonds (Liquid Alpha) + +```rust +if Yuma3On::::get(netuid) { + // Get existing bonds + let mut bonds = Self::get_bonds_sparse_fixed_proportion(netuid); + + // Remove bonds to recently registered neurons + let last_tempo: u64 = current_block.saturating_sub(tempo); + bonds = scalar_vec_mask_sparse_matrix( + &bonds, + last_tempo, + &block_at_registration, + &|last_tempo, registered| last_tempo <= registered, + ); + + // Compute new bonds with liquid alpha + ema_bonds = Self::compute_bonds_sparse(netuid, &weights_for_bonds, &bonds, &consensus); + + // Normalize bonds and calculate validator emissions + let mut ema_bonds_norm = ema_bonds.clone(); + inplace_col_normalize_sparse(&mut ema_bonds_norm, n); + + let total_bonds_per_validator: Vec = + row_sum_sparse(&mat_vec_mul_sparse(&ema_bonds_norm, &incentive)); + + dividends = vec_mul(&total_bonds_per_validator, &active_stake); + inplace_normalize(&mut dividends); +} +``` + +#### Original Yuma Bonds + +```rust +else { + // Get existing bonds + let mut bonds: Vec> = Self::get_bonds_sparse(netuid); + + // Remove bonds to recently registered neurons + bonds = scalar_vec_mask_sparse_matrix(/* ... */); + inplace_col_normalize_sparse(&mut bonds, n); + + // Compute bond deltas from weights and stake + let mut bonds_delta: Vec> = + row_hadamard_sparse(&weights_for_bonds, &active_stake); + inplace_col_normalize_sparse(&mut bonds_delta, n); + + // Apply EMA to bonds + ema_bonds = Self::compute_ema_bonds_normal_sparse(&bonds_delta, &bonds, netuid); + inplace_col_normalize_sparse(&mut ema_bonds, n); + + // Calculate dividends: d_i = SUM(j) b_ij * incentive_j + dividends = matmul_transpose_sparse(&ema_bonds, &incentive); + inplace_normalize(&mut dividends); +} +``` + +**Bond Dynamics:** +- **[Bonds](../resources/glossary.md#validator-miner-bonds)**: Measure validator-miner relationships over time +- **EMA Updates**: $B_{ij}^{(t)} = \alpha \Delta B_{ij} + (1-\alpha) B_{ij}^{(t-1)}$ +- **Validator Emissions**: Validators earn based on bonds to high-incentive miners + +### 10. Emission Distribution + +```rust +// Calculate combined emissions for pruning scores +let combined_emission: Vec = incentive + .iter() + .zip(dividends.clone()) + .map(|(ii, di)| ii.saturating_add(di)) + .collect(); + +let emission_sum: I32F32 = combined_emission.iter().sum(); + +// Separate server and validator emissions +let mut normalized_server_emission: Vec = incentive.clone(); +let mut normalized_validator_emission: Vec = dividends.clone(); +let mut normalized_combined_emission: Vec = combined_emission.clone(); + +// Normalize based on total emission sum +inplace_normalize_using_sum(&mut normalized_server_emission, emission_sum); +inplace_normalize_using_sum(&mut normalized_validator_emission, emission_sum); +inplace_normalize(&mut normalized_combined_emission); + +// Handle zero emission case +if emission_sum == I32F32::from(0) { + if is_zero(&active_stake) { + normalized_validator_emission.clone_from(&stake); + normalized_combined_emission.clone_from(&stake); + } else { + normalized_validator_emission.clone_from(&active_stake); + normalized_combined_emission.clone_from(&active_stake); + } +} +``` + +**Emission Fallback:** +When no weights are set (emission_sum = 0), emissions default to stake proportions. + +### 11. RAO Conversion + +```rust +// Convert to actual currency amounts +let float_rao_emission: I96F32 = I96F32::saturating_from_num(rao_emission); + +let server_emission: Vec = normalized_server_emission + .iter() + .map(|se| { + let scaled = I96F32::saturating_from_num(*se) + .saturating_mul(float_rao_emission); + scaled.saturating_to_num::().into() + }) + .collect(); + +let validator_emission: Vec = normalized_validator_emission + .iter() + .map(|ve| { + let scaled = I96F32::saturating_from_num(*ve) + .saturating_mul(float_rao_emission); + scaled.saturating_to_num::().into() + }) + .collect(); +``` + +**[RAO](../resources/glossary.md#rao) Scaling:** +Normalized emission proportions are scaled by the total RAO emission amount to get actual currency values. + +### 12. State Updates + +```rust +// Store computed values +StakeWeight::::insert(netuid, cloned_stake_weight); +Active::::insert(netuid, active); +Emission::::insert(netuid, combined_emission); +Rank::::insert(netuid, cloned_ranks); +Trust::::insert(netuid, cloned_trust); +Consensus::::insert(netuid, cloned_consensus); +Incentive::::insert(netuid, cloned_incentive); +Dividends::::insert(netuid, cloned_dividends); +PruningScores::::insert(netuid, cloned_pruning_scores); +ValidatorTrust::::insert(netuid, cloned_validator_trust); +ValidatorPermit::::insert(netuid, new_validator_permits); + +// Update bonds for validators with permits +new_validator_permits + .iter() + .zip(validator_permits) + .zip(ema_bonds) + .enumerate() + .for_each(|(i, ((new_permit, validator_permit), ema_bond))| { + if *new_permit { + let new_bonds_row: Vec<(u16, u16)> = ema_bond + .iter() + .map(|(j, value)| (*j, fixed_proportion_to_u16(*value))) + .collect(); + Bonds::::insert(netuid, i as u16, new_bonds_row); + } else if validator_permit { + Bonds::::insert(netuid, i as u16, vec![]); + } + }); +``` + +**Storage Updates:** +All computed values are stored for: +- **External queries**: Allow inspection of consensus state +- **Next epoch**: Bonds and permits carry forward +- **Pruning**: Combined emission determines neuron removal + +### 13. Return Emission Tuples + +```rust +// Create final emission mapping +hotkeys + .into_iter() + .map(|(uid_i, hotkey)| { + ( + hotkey, + server_emission[uid_i as usize], // Miner emission + validator_emission[uid_i as usize], // Validator emission + ) + }) + .collect() +``` diff --git a/docs/navigating-subtensor/function-reference.md b/docs/navigating-subtensor/function-reference.md new file mode 100644 index 0000000000..337b21516e --- /dev/null +++ b/docs/navigating-subtensor/function-reference.md @@ -0,0 +1,504 @@ +--- +title: "Function Reference & Architecture Guide" +--- + +# Function Reference & Architecture Guide + +This page explains how the core Yuma Consensus and emission functions work together, and provides a comprehensive reference for all key functions in the system. + +## How run_epoch and run_coinbase Relate + +A common source of confusion is understanding how `run_epoch.rs` and `run_coinbase.rs` work together despite neither file directly importing the other. + +### The Architecture + +Both files are part of the **same Substrate pallet implementation**: + +```rust +// In lib.rs +pub mod coinbase; // Contains run_coinbase.rs +pub mod epoch; // Contains run_epoch.rs + +// Both files use: +impl Pallet { + // Functions from both files become methods on the same struct +} +``` + +The `use super::*;` at the top of each file imports everything from the parent module, giving both files access to: +- The same `Pallet` struct +- All storage items (shared blockchain state) +- All other modules in the pallet + +### The Call Chain + +```rust +// Every block: coinbase accumulates emissions +Self::run_coinbase(block_emission) + +// Every tempo: coinbase calls epoch for consensus +if Self::should_run_epoch(netuid, current_block) { + Self::drain_pending_emission(/* accumulated emissions */); + // Inside drain_pending_emission: + let hotkey_emission = Self::epoch(netuid, pending_alpha); + // ^^^^^^^^^^^^ + // Calls function defined in run_epoch.rs! +} +``` + +### Timing Relationship + +The architecture creates a **batch processing pattern**: + +1. **Every Block (Fast)**: `run_coinbase()` injects liquidity and accumulates emissions +2. **Every Tempo (Slow)**: `epoch()` processes accumulated emissions through consensus + +**Example**: If tempo = 360 blocks (~60 minutes): +- 359 blocks: Only coinbase runs, accumulating emissions +- 1 block: Coinbase triggers epoch, which processes all accumulated emissions + +--- + +## Core Function Reference + +### Epoch Functions (`run_epoch.rs`) + +#### `epoch(netuid, rao_emission) -> Vec<(AccountId, AlphaCurrency, AlphaCurrency)>` +**Main Yuma Consensus Implementation** + +Processes validator weights and distributes emissions through the complete [Yuma Consensus](../learn/yuma-consensus.md) algorithm: + +1. **Activity filtering** - Only recently active validators influence consensus +2. **Stake calculation** - Validator permit assignment based on top-k stake +3. **Weight processing** - Consensus calculation with κ-clipping +4. **Miner ranking** - Aggregate rankings weighted by validator stake +5. **Bond formation** - EMA bond updates between validators and miners +6. **Emission distribution** - Final allocation to miners and validators + +**Called by:** `drain_pending_emission()` in coinbase during epoch timing + +--- + +#### `epoch_dense(netuid, rao_emission) -> Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)>` +**Dense Matrix Version (Testing Only)** + +Alternative implementation using dense matrices instead of sparse ones. Contains identical consensus logic but with different data structures for testing and validation purposes. + +**Use Case:** Unit tests, consensus algorithm verification, debugging + +--- + +### Configuration & Parameter Functions + +#### `get_float_rho(netuid) -> I32F32` +**Bond EMA Parameter Retrieval** + +Retrieves the rho parameter used in exponential moving average calculations for bond updates. + +**Connection:** Implements the α parameter in bond EMA formula: `B_ij^(t) = α ΔB_ij + (1-α) B_ij^(t-1)` + +--- + +#### `get_float_kappa(netuid) -> I32F32` +**Consensus Threshold Parameter** + +Gets the consensus threshold κ (kappa) that determines what fraction of stake must agree for consensus. + +**Default:** 0.5 (51% of stake must agree) +**Related:** [Consensus clipping mechanism](../learn/yuma-consensus.md#clipping) + +--- + +#### `get_float_bonds_penalty(netuid) -> I32F32` +**Bond Penalty Factor** + +Retrieves the penalty factor β applied when validator weights exceed consensus. + +**Formula:** `W̃_ij = (1-β) W_ij + β W̄_ij` +**Purpose:** [Penalizes out-of-consensus bonds](../learn/yuma-consensus.md#penalizing-out-of-consensus-bonds) + +--- + +### Data Retrieval Functions + +#### `get_block_at_registration(netuid) -> Vec` +**Registration Block History** + +Returns when each neuron was last registered, used to filter outdated weights. + +**Usage:** Prevents validators from voting on miners that re-registered after the weight was set + +--- + +#### `get_weights_sparse(netuid) -> Vec>` +**Sparse Weight Matrix Retrieval** + +Fetches the weight matrix W_ij in sparse format for memory efficiency. + +**Format:** `Vec` where `validator_weights = Vec<(miner_uid, weight)>` + +--- + +#### `get_weights(netuid) -> Vec>` +**Dense Weight Matrix Retrieval** + +Fetches the complete weight matrix as a dense n×n matrix. + +**Usage:** Testing and small subnets where memory efficiency is less critical + +--- + +#### `get_bonds_sparse(netuid) -> Vec>` +**Sparse Bond Matrix Retrieval** + +Gets the bond matrix B_ij in sparse format, representing validator-miner relationships. + +**Connection:** [Bond mechanics](../learn/yuma-consensus.md#bonding-mechanics) in Yuma Consensus + +--- + +#### `get_bonds(netuid) -> Vec>` +**Dense Bond Matrix Retrieval** + +Retrieves the complete bond matrix as a dense n×n matrix. + +--- + +#### `get_bonds_fixed_proportion(netuid) -> Vec>` +**Proportional Bond Matrix** + +Returns bonds normalized to fixed proportions (0-1 scale). + +--- + +#### `get_bonds_sparse_fixed_proportion(netuid) -> Vec>` +**Sparse Proportional Bonds** + +Sparse version of proportional bond matrix. + +--- + +### Bond Computation Functions + +#### `compute_ema_bonds_normal_sparse(bonds_delta, bonds, netuid) -> Vec>` +**Original Yuma Bond EMA (Sparse)** + +Computes exponential moving average of bonds using a fixed α parameter for all validator-miner pairs. + +**Algorithm:** Traditional EMA with single learning rate +**Used When:** Liquid Alpha is disabled + +--- + +#### `compute_ema_bonds_normal(bonds_delta, bonds, netuid) -> Vec>` +**Original Yuma Bond EMA (Dense)** + +Dense matrix version of the original bond EMA calculation. + +--- + +#### `compute_bonds(netuid, weights, bonds, consensus) -> Vec>` +**Liquid Alpha Bond Computation (Dense)** + +Advanced bond calculation with consensus-based α parameters. Each validator-miner pair gets a unique EMA rate. + +**Algorithm:** `α_ij = f(consensus_j, weight_ij, bond_ij)` +**Used When:** Liquid Alpha is enabled (Yuma3) + +--- + +#### `compute_bonds_sparse(netuid, weights, bonds, consensus) -> Vec>` +**Liquid Alpha Bond Computation (Sparse)** + +Sparse matrix version of the liquid alpha bond computation for better performance. + +--- + +### Liquid Alpha Functions + +#### `compute_liquid_alpha_values(netuid, weights, bonds, consensus) -> Vec>` +**Consensus-Based Alpha Matrix (Dense)** + +Calculates individual α parameters for each validator-miner bond based on consensus alignment. + +**Innovation:** Variable learning rates that adapt to consensus agreement + +--- + +#### `compute_liquid_alpha_values_sparse(netuid, weights, bonds, consensus) -> Vec>` +**Consensus-Based Alpha Matrix (Sparse)** + +Sparse version of the liquid alpha calculation, outputting dense alpha matrix. + +--- + +#### `alpha_sigmoid(consensus, weight, bond, alpha_low, alpha_high, steepness) -> I32F32` +**Alpha Parameter Calculation** + +Sigmoid function that determines EMA learning rate based on consensus deviation. + +**Formula:** `α = α_low + sigmoid(deviation) × (α_high - α_low)` +**Purpose:** Faster adaptation when validators diverge from consensus + +--- + +#### `compute_disabled_liquid_alpha(netuid) -> I32F32` +**Fallback Alpha Calculation** + +Computes traditional fixed α parameter when liquid alpha is disabled. + +--- + +### Administrative Functions + +#### `do_set_alpha_values(origin, netuid, alpha_low, alpha_high) -> DispatchResult` +**Alpha Parameter Configuration** + +Allows subnet owners to configure liquid alpha parameters. + +**Validation:** Ensures parameters are within acceptable ranges to prevent system instability + +--- + +#### `do_reset_bonds(netuid, account_id) -> DispatchResult` +**Bond Reset Mechanism** + +Resets bonds for a specific account, typically used during deregistration. + +--- + +### Complete Coinbase Function Reference (`run_coinbase.rs`) + +### Primary Emission Functions + +#### `run_coinbase(block_emission: U96F32)` +**Core Emission Distribution Engine** + +Main function that runs every block to implement the [injection phase](../learn/emissions.md#injection) of the emission system. + +**Process Flow:** +1. Calculate price-proportional TAO distribution across subnets +2. Inject TAO and alpha liquidity into AMM pools +3. Accumulate pending emissions for epoch distribution +4. Execute epochs when tempo timing is reached + +**Related:** [Price-based distribution](../learn/emissions.md#tao-reserve-injection), [alpha injection](../learn/emissions.md#alpha-reserve-injection) + +--- + +### Emission Calculation Functions + +#### `calculate_dividends_and_incentives(netuid, hotkey_emission) -> (BTreeMap, BTreeMap)` +**Emission Type Separation** + +Separates epoch results into miner incentives and validator dividends, handling child key delegation. + +**Output:** +- Incentives: Direct miner rewards in alpha +- Dividends: Validator rewards (subject to take and delegation) + +--- + +#### `calculate_dividend_distribution(pending_alpha, pending_tao, tao_weight, stake_map, dividends) -> (BTreeMap, BTreeMap)` +**Dividend Type Allocation** + +Splits validator dividends between alpha (subnet-specific) and TAO (root) distributions based on stake composition. + +**Algorithm:** Proportional split based on alpha vs. TAO stake holdings +**Connection:** [Validator stake weight](../learn/emissions.md#extraction) calculations + +--- + +#### `calculate_dividend_and_incentive_distribution(netuid, pending_tao, pending_validator_alpha, hotkey_emission, tao_weight) -> (BTreeMap, (BTreeMap, BTreeMap))` +**Comprehensive Distribution Calculation** + +Orchestrates the complete emission distribution process combining incentives and dividend calculations. + +--- + +### Distribution Functions + +#### `distribute_dividends_and_incentives(netuid, owner_cut, incentives, alpha_dividends, tao_dividends)` +**Final Emission Distribution** + +Executes the actual distribution of rewards to participants, applying takes and delegation rules. + +**Process:** +1. Distribute subnet owner cut (configurable %, default 18%) +2. Distribute miner incentives (50% of total when miners active) +3. Apply validator take percentages +4. Distribute remaining rewards to stakers proportionally + +--- + +#### `get_parent_child_dividends_distribution(hotkey, netuid, dividends) -> Vec<(T::AccountId, AlphaCurrency)>` +**Child Key Delegation Distribution** + +Handles complex validator dividend distribution when child keys (delegation) are involved. + +**Features:** +- Proportional distribution based on delegation amounts +- Validator take extraction before delegation +- Support for multi-level delegation hierarchies + +--- + +### Utility Functions + +#### `get_stake_map(netuid, hotkeys) -> BTreeMap` +**Stake Information Aggregation** + +Collects alpha and TAO stake information for all provided hotkeys. + +**Output:** `(alpha_stake, tao_stake)` pairs for dividend calculations + +--- + +#### `get_self_contribution(hotkey, netuid) -> u64` +**Self-Stake Calculation** + +Calculates how much stake a validator contributes themselves (vs. delegated stake). + +**Usage:** Determines validator's share of their own emissions before delegation splits + +--- + +### Epoch Timing Functions + +#### `should_run_epoch(netuid, current_block) -> bool` +**Epoch Timing Check** + +Determines if a subnet should run its epoch based on tempo scheduling. + +**Formula:** `(block_number + netuid + 1) % (tempo + 1) == 0` +**Connection:** [Tempo-based extraction](../learn/emissions.md#extraction) timing + +--- + +#### `blocks_until_next_epoch(netuid, tempo, block_number) -> u64` +**Epoch Countdown** + +Calculates how many blocks remain until the next epoch for a subnet. + +**Usage:** Monitoring and prediction of epoch timing + +--- + +### Primary Orchestration Function + +#### `drain_pending_emission(netuid, pending_alpha, pending_tao, pending_swapped, owner_cut)` +**Epoch Execution Orchestrator** + +Coordinates the complete emission distribution process by: +1. Calling `epoch()` to run Yuma Consensus +2. Calculating emission splits (50%/50% miner/validator when miners active) +3. Processing delegation and takes +4. Distributing final rewards + +**Critical Bridge:** Connects coinbase injection with epoch consensus and final distribution + +--- + +### Timing Coordination Functions + +#### `should_run_epoch(netuid, current_block) -> bool` +**Epoch Timing Logic** + +**Formula**: `(block_number + netuid + 1) % (tempo + 1) == 0` + +This staggered timing ensures: +- Different subnets run epochs at different blocks (load balancing) +- Predictable tempo-based scheduling +- Synchronized network behavior + +--- + +## System Integration + +### Data Flow Architecture + +```mermaid +graph TD + A[run_coinbase] --> B[Price Calculation] + B --> C[TAO/Alpha Injection] + C --> D[Accumulate Pending] + D --> E{Epoch Time?} + E -->|No| F[Continue Next Block] + E -->|Yes| G[drain_pending_emission] + G --> H[Self::epoch - Yuma Consensus] + H --> I[calculate_dividends_and_incentives] + I --> J[distribute_dividends_and_incentives] + F --> A + J --> A +``` + +### Shared Storage + +Both modules read/write the same blockchain storage: + +- **`PendingEmission`**: Accumulated alpha for distribution +- **`Bonds`**: Validator-miner EMA relationships +- **`ValidatorPermit`**: Top-k stake validation rights +- **`Weights`**: Validator rankings of miners + +### Key Integration Points + +1. **Temporal coordination**: Coinbase accumulates, epoch processes, distribution executes +2. **Economic consistency**: Mathematical formulas from docs implemented across both modules +3. **State synchronization**: Shared storage ensures consistent view of network state +4. **Performance optimization**: Sparse matrices for large subnets, batched processing + +--- + +## Essential Function Categories + +### Configuration & Parameters +- `get_float_kappa(netuid)` - Consensus threshold (default 51%) +- `get_float_bonds_penalty(netuid)` - Penalty factor for out-of-consensus weights +- `do_set_alpha_values()` - Configure liquid alpha parameters + +### Data Retrieval +- `get_weights_sparse(netuid)` - Validator weight matrix (memory efficient) +- `get_bonds_sparse(netuid)` - Validator-miner bond matrix +- `get_block_at_registration(netuid)` - Filter outdated weights + +### Economic Distribution +- `calculate_dividends_and_incentives()` - Separate miner vs validator rewards +- `get_self_contribution()` - Calculate validator's own stake contribution +- `blocks_until_next_epoch()` - Timing prediction for monitoring + +--- + +## Real-World Analogy + +Think of the system like a **payroll company**: + +- **Coinbase** = **Accounting Department** + - Tracks company revenue daily (price calculations) + - Allocates funds to divisions (subnet injection) + - Accumulates amounts owed (pending emissions) + +- **Epoch** = **HR Department** + - Evaluates employee performance periodically (consensus) + - Determines merit-based bonuses (miner incentives) + - Calculates manager commissions (validator dividends) + +Both departments work for the same company (Pallet), share the same database (Storage), but have different responsibilities and timing. + +--- + +## Why This Architecture Matters + +Understanding this relationship is crucial for: + +- **Debugging**: Issues could originate in either injection or consensus phases +- **Development**: Features often need both accumulation and distribution logic +- **Performance**: Timing affects network scalability and economic security +- **Economics**: Coordination between modules affects token incentive alignment + +This architecture elegantly coordinates complex economic mechanisms while maintaining clean separation of concerns and code organization. + +## Documentation Links + +- **Conceptual**: [Yuma Consensus](../learn/yuma-consensus.md) | [Emissions](../learn/emissions.md) | [Staking](../staking-and-delegation/delegation.md) +- **Implementation**: [Epoch Details](./epoch.md) | [Coinbase Details](./emissions-coinbase.md) | [Swap Mechanics](./swap-stake.md) \ No newline at end of file diff --git a/docs/navigating-subtensor/index.md b/docs/navigating-subtensor/index.md new file mode 100644 index 0000000000..42ec6a3805 --- /dev/null +++ b/docs/navigating-subtensor/index.md @@ -0,0 +1,52 @@ +--- +title: "Navigating the Subtensor Codebase" +--- + + +# Navigating the Subtensor Codebase + +The heart of Bittensor is Subtensor, the L1 substrate blockchain that computes and records all transactions, as well as the internal tokenomic processes (Yuma Consensus and liquidity emission) that drive the system. + +This section of the docs is designed make the codebase more accessible by guiding the reader through the implementation of these critical functions in code. Each implementation page traces the complete flow of operations from initial function calls through to final state changes. + +We recommend reading our conceptual explainer docs before diving into the implementation details: + +- [Emissions](../learn/emissions.md) +- [Yuma Consensus](../learn/yuma-consensus.md) +- [Staking/Delegation](../staking-and-delegation/delegation.md) + +## Implementation Topics + +This section covers the following implementation-focused topics: + +### [Emissions and Coinbase](./emissions-coinbase.md) +Deep dive into the coinbase mechanism that drives TAO and alpha emissions across subnets. Learn how `run_coinbase()` calculates and distributes emissions, manages liquidity pools, and orchestrates the emission cycles of the subnets within the overall network by triggering their epochs. + +**Key areas covered:** +- Block emission calculation and distribution +- TAO and alpha injection mechanics +- Subnet price-based emission allocation +- Pending emission accumulation and drainage +- Owner cuts and root dividends +- Triggering of the epoch + +### [Epoch Mechanism](./epoch.md) +Comprehensive exploration of the epoch function that implements Yuma Consensus. Understand how validator weights are processed, consensus is computed, and emissions are allocated to participants. + +**Key areas covered:** +- Weight processing and validation +- Consensus calculation and clipping +- Bond computation and EMA updates +- Rank, trust, and incentive calculations +- Emission distribution to miners and validators + +### [Swap and Staking](./swap-stake.md) +Detailed examination of the staking and unstaking mechanisms, including the automated market maker (AMM) functionality that enables TAO ↔ alpha conversions. + +**Key areas covered:** +- Stake addition and removal flows +- AMM price calculations +- TAO to alpha conversions +- Liquidity pool management +- Slippage and price protection + diff --git a/docs/navigating-subtensor/swap-stake.md b/docs/navigating-subtensor/swap-stake.md new file mode 100644 index 0000000000..0f1293c8e1 --- /dev/null +++ b/docs/navigating-subtensor/swap-stake.md @@ -0,0 +1,184 @@ +--- +title: "Staking Implementation" +--- + +# Staking Implementation + +This page provides a detailed examination of how staking is implemented in the Subtensor codebase. + +Each subnet maintains its own AMM pool with TAO and Alpha reserves. When you stake, your TAO enters the subnet's TAO reserve and you receive Alpha tokens that represent your stake in that specific subnet. Alpha stake determines consensus weight and emission share for validators within a given subnet. + +See [Staking/Delegation Overview](../staking-and-delegation/delegation) + +:::tip Key Concept +**Stake is held in Alpha (α) token denominations** on each subnet. The exception is the Root Subnet (subnet 0), in which stake is held in TAO. +::: + +## Core Staking Operations + +### Stake Addition: `do_add_stake()` + +Located in `subtensor/pallets/subtensor/src/staking/add_stake.rs`, this function converts TAO to Alpha through the subnet's AMM. + +#### Function Signature +```rust +pub fn do_add_stake( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + netuid: NetUid, + stake_to_be_added: TaoCurrency, +) -> DispatchResult +``` + +#### Implementation Flow + +##### 1. Validation and Fee Calculation +```rust +// Ensure the caller is signed +let coldkey = ensure_signed(origin)?; + +// Ensure subnet exists and is enabled for staking +ensure!(Self::if_subnet_exist(netuid), Error::::SubnetNotExists); +Self::ensure_subtoken_enabled(netuid)?; + +// Calculate minimum amount including swap fees +let min_stake = DefaultMinStake::::get(); +let fee = T::SwapInterface::sim_swap(netuid.into(), OrderType::Buy, min_stake.into()) + .map(|res| res.fee_paid) + .unwrap_or(T::SwapInterface::approx_fee_amount(netuid.into(), min_stake.into())); +let min_amount = min_stake.saturating_add(fee.into()); + +// Validate minimum stake amount (must cover both stake and fees) +ensure!(stake_to_be_added >= min_amount, Error::::AmountTooLow); +``` + +##### 2. Balance Verification +```rust +// Check coldkey has sufficient TAO balance +let current_balance = Self::get_coldkey_balance(&coldkey); +ensure!( + current_balance >= stake_to_be_added.into(), + Error::::NotEnoughBalanceToStake +); +``` + +##### 3. TAO Removal and Alpha Conversion +```rust +// Remove TAO from coldkey balance +let tao_staked = Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added.into())?; + +// Convert TAO to Alpha through subnet AMM +Self::stake_into_subnet( + &hotkey, + &coldkey, + netuid, + tao_staked.to_u64().into(), + T::SwapInterface::max_price().into(), // Accept market price + true, // drop_fees = true for add_stake +)?; +``` + +The `stake_into_subnet` function handles the AMM conversion: +- Uses 1:1 conversion for Stable subnets (mechanism_id = 0) +- Calls `swap_tao_for_alpha()` for dynamic subnets (mechanism_id = 1) +- Updates subnet TAO and Alpha reserves +- Credits Alpha tokens to the hotkey's stake + +The `swap_tao_for_alpha()` function: +- Executes the actual AMM swap operation +- Calculates the amount of Alpha tokens received for the given TAO input +- Handles slippage and fee calculations +- Updates the subnet's liquidity pool reserves + +##### 4. Event Emission +```rust +// Emit staking event with actual amounts +Self::deposit_event(Event::StakeAdded { + account_id: hotkey.clone(), + balance_staked: stake_to_be_added, + balance_increased: Self::get_total_stake_for_hotkey(&hotkey), +}); +``` + +### Stake Removal: `do_remove_stake()` + +The unstaking process converts Alpha stake back to TAO through the subnet's AMM. + +#### Function Signature +```rust +pub fn do_remove_stake( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + netuid: NetUid, + alpha_unstaked: AlphaCurrency, +) -> DispatchResult +``` + +#### Implementation Flow + +##### 1. Validation +```rust +let coldkey = ensure_signed(origin)?; + +// Ensure subnet exists and is enabled +ensure!(Self::if_subnet_exist(netuid), Error::::SubnetNotExists); +Self::ensure_subtoken_enabled(netuid)?; + +// Verify sufficient Alpha stake exists on this subnet +let alpha_on_subnet = Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); +ensure!( + alpha_on_subnet >= alpha_unstaked, + Error::::NotEnoughStakeToWithdraw +); +``` + +##### 2. Alpha to TAO Conversion +```rust +// Convert Alpha back to TAO through subnet AMM +let tao_received = Self::unstake_from_subnet( + &hotkey, + &coldkey, + netuid, + alpha_unstaked, + TaoCurrency::ZERO, // min_price = 0 (accept any price) + true, // drop_fees = true for remove_stake +)?; + +// Add the received TAO back to coldkey balance +Self::add_balance_to_coldkey_account(&coldkey, tao_received.into())?; +``` + +The `unstake_from_subnet` function: +- Removes Alpha from hotkey's stake +- Calls `swap_alpha_for_tao()` to convert Alpha → TAO +- Updates subnet reserves (Alpha increases, TAO decreases) +- Returns the TAO amount received after fees + +The `swap_alpha_for_tao()` function: +- Executes the actual AMM swap operation +- Calculates the amount of TAO tokens received for the given Alpha input +- Handles slippage and fee calculations +- Updates the subnet's liquidity pool reserves + +## Price Protection + +The staking system includes price protection mechanisms to prevent excessive slippage during AMM operations. Each staking operation has a corresponding `_limit` variant that accepts price protection parameters: + +- `do_add_stake_limit()` - Staking with price protection +- `do_remove_stake_limit()` - Unstaking with price protection + +These functions accept `limit_price` and `allow_partial` parameters to control protection behavior. See [Price Protection Guide](../learn/price-protection.md) for detailed usage and examples. + +## Error Handling + +### Common Error Types + +```rust +Error::::SubnetNotExists // Subnet doesn't exist +Error::::AmountTooLow // Below minimum stake + fees +Error::::NotEnoughBalanceToStake // Insufficient TAO balance +Error::::NotEnoughStakeToWithdraw // Insufficient Alpha stake +Error::::SlippageTooHigh // Price protection triggered (strict mode) +Error::::ZeroMaxStakeAmount // No amount executable within price limit +Error::::InsufficientLiquidity // AMM simulation failed +``` diff --git a/docs/reference/_bittensor-api-ref.md b/docs/reference/_bittensor-api-ref.md index b24194346c..15900f68a8 100644 --- a/docs/reference/_bittensor-api-ref.md +++ b/docs/reference/_bittensor-api-ref.md @@ -14,7 +14,7 @@ The `Subtensor` is utilized for managing interactions with the subtensor chain. # Creating a default chain connection to remote finney instance. sub = bt.subtensor() -# Parsing --subtensor.network and --subtensor.chain_endpoint from the command line +# Parsing --subtensor.network and --network from the command line sub = bt.subtensor( config = bt.subtensor.config() ) # Connecting subtensor's default local entrypoint "ws://127.0.0.1:9944" diff --git a/docs/research/_halvings-problem.md b/docs/research/_halvings-problem.md new file mode 100644 index 0000000000..21926a334c --- /dev/null +++ b/docs/research/_halvings-problem.md @@ -0,0 +1,158 @@ +--- +title: "Token Halvings Problem and Solution: FAQ" +--- + +# Token Halvings Problem and Solution: FAQ + +This page introduces the basic concepts for this [white paper](https://github.com/mcjkula/papers/blob/main/dtao-halving-synchronization-2025-v1.pdf) on a problem (and its solution) in the design of Bittensor's Emission halving schedule. + +For a long-form, plain language walk-through, see: [Token Halvings Problem and Solution](./synchronized-halving.md). + +## FAQ + +### What’s the core problem? +Later subnets are structurally disadvantaged: every TAO halving creates a new class of subnets with weaker tokenomics, making them more prone to deregistration, even if they behave identically to earlier cohorts. + +### Why do we need to act before the first TAO halving? + +Because the first halving already creates two permanent classes. Once split, later subnets will be persistently weaker and more deregistration-prone. + +The crux is that injections shrink with the global TAO halving index k, while emissions depend on the subnet’s own ALPHA halving index n. The gap m = n - k controls outcomes, giving exponential advantageous 2^(k-n) to older subnets. + +### What is ADR? + +ADR is the emissions-to-injections ratio. It measures how much ALPHA goes to people (emissions) relative to how much is put into the pool (injections). A higher ADR means liquidation happens at a deeper discount. In the current protocol, ADR tracks 2^(k - n), underlying the subnet cohort asymmetry. + +### Doesn’t buy pressure balance things out between newer and older subnets? + +Not symmetrically. Unstake/slippage depends only on the ALPHA reserve. As injections shrink with k while emissions remain at n, identical sell fractions yank out more TAO in later cohorts. Systematic sell flows (e.g., root) happen every block; buy flows are sporadic. + +### What is the synchronized-halving fix in plain words? + +Make both ALPHA injection and ALPHA emission halve with the same global schedule (k). That kills the gap m. Consequences: no interval compression asymmetry, no liquidation discount vs spot, and liquidity impact becomes cohort-invariant for the same behavior. + + +### What happens to the “21M per subnet” idea? + +This design concept is the root of the problem. Keeping a fixed 21M for every subnet conflicts with eliminating the cohort disadvantage. Synchronizing both ALPHA components to k removes the disadvantage but implies per-subnet max supply depends on registration time. + + +### What are the trade-offs of synchronizing? +- Pro: Removes cohort classes (fairness), simpler mental model, predictable dynamics. +- Con: Per-subnet max ALPHA varies with registration time; requires accepting supply differences and potentially using Zeno-halvings to allow emissions to scale down without limit. + +### Can we fix it by only changing how ALPHA halvings work (emissions-only)? + +That slows interval compression but leaves ADR/liquidity asymmetries intact. You still get unequal max supplies and persistent cohort differences. + +### What is “liquidity impact” and why does it hurt later cohorts more? +It’s the fraction of TAO reserves removed when selling ALPHA. For unstaking, the impact depends only on the ALPHA reserve. Later cohorts get smaller injections into the pool, yet the same emissions to participants, so the same sell fraction removes more TAO. + +### What is the “haircut” on liquidation? +It’s the discount between liquidation price and spot. With ADR>1 (typical for late cohorts), P_L = P/ADR ⇒ a large haircut. Example: ADR=32 ⇒ P_L is P/32 (~97% discount). + +### How does the root proportion change across cohorts? +Later cohorts’ total issuance grows slower over shared horizons, so the root proportion declines more slowly. Practically, root sells a larger share for longer (another persistent disadvantage for later cohorts). + +### What if we do nothing? + +We entrench permanent classes. Later subnets will be weaker across liquidity, liquidation, and incentive trajectories, and be more vulnerable to deregistration even with identical performance. Subnets will also reach their maximum supply in the coming ~10 years (much quicker than intended) and thus stop having emissions without anything to incentivize validators/miners. + +### What changes immediately after the first halving? + +Material shifts appear right away (e.g., the baseline liquidity impact for the same sell fraction rises significantly from ~29% to ~45% in examples discussed). The divergence then compounds with subsequent halvings. + +### What are Zeno-halvings + +Zeno-halvings, based on Zeno's Paradox of movement, embodied in the race between [Achilles and the tortoise](https://en.wikipedia.org/wiki/Infinity#Zeno:_Achilles_and_the_tortoise), and the idea that emissions should be able to halve infinitely, with the emissions becoming smaller and smaller, requiring higher precision token denominations. + +That preserves the intended scaling without “falling off a cliff.” + +### I run a subnet today—what’s the practical takeaway? + +Early cohorts enjoy structural advantages. If the goal is a fair, durable ecosystem that welcomes future subnets, synchronizing the halving schedules (and acknowledging variable max supplies) removes the class disadvantage and simplifies operations. + + +## GLOSSARY + +### TAO (τ) + +The main network token. Its block reward halves on a global schedule. + +### ALPHA (α) + +A subnet’s token. Each subnet has its own ALPHA. ALPHA is created two ways: injected into the AMM and emitted to participants. + +### TAO halving index (k) + +How many global TAO halvings have happened (0, 1, 2, ...). Bigger k means smaller TAO block rewards. + +### ALPHA halving index (n) + +How many ALPHA halvings a specific subnet has gone through (0, 1, 2, ...). Bigger n means smaller ALPHA emissions for that subnet. + +### Cohort gap (m = n - k) + +The single number that explains cohort differences. If m is negative (new subnet registered after multiple TAO halvings), the subnet is disadvantaged; if positive, it’s an earlier cohort with different dynamics. + +### Injection (Δα) + +ALPHA minted into the AMM reserves. It scales with the TAO halving index k (shrinks as k grows). Think: top-ups to the pool driven by global TAO emissions. + +### Emission (Δα′) + +ALPHA minted directly to participants (miners, nominators, etc.) based on the subnet’s own schedule n. + +### TERP (TAO Emission Ratio Property) + +The rule that allocates TAO injections across subnets according to smoothed (EMA) prices. + +### EMA price (p̃) + +Exponentially weighted moving average price; a smoothed price used by TERP to avoid reacting to short-term noise. + +### AMM (Automated Market Maker) + +The on-chain market for swapping TAO and ALPHA. We use the constant-product AMM as the baseline mental model. + +### Liquidity impact (R) + +When users sell/unstake ALPHA, R is the fraction of TAO reserves removed from the AMM. Higher R means worse slippage/impact. + +### ADR (emissions-to-injections ratio) + +Simple version: “How much ALPHA goes to people vs how much is put into the pool.” Formally, ADR_k,n ≈ 2^(k - n) under the baseline. Bigger ADR ⇒ liquidation prices are a smaller fraction of spot (deeper discount). + +### Spot price (P) + +TAO per ALPHA using AMM reserves (τ/α in the pool). + +### Liquidation price (P_L) + +TAO per ALPHA using outstanding supply instead of pool reserves. Under baseline it’s P_L = P / ADR. + +### Haircut (h) + +The liquidation discount relative to spot: h = 1 - (P_L / P). Higher h means worse outcomes on liquidation. + +### Root proportion (r) + +How rewards split between the root stakers and subnet validators; drifts over time with issuance. + +### Synchronized halving (explored fix) + +Make both ALPHA components (injection and emission) follow the global TAO schedule (k). This removes the cohort gap m. + +### Zeno-halvings (precision fix) + +Increase token precision so halvings can continue below the smallest unit; avoids the emission tail rounding to zero. + +### Deregistration + +When a subnet fails to meet economic/operation criteria and gets removed. Later cohorts are more vulnerable under current rules. + +### Cohort/class + +Subnets born between TAO halvings. Each halving creates a new class with different tokenomics under the current design. + + diff --git a/docs/research/_synchronized-halving.md b/docs/research/_synchronized-halving.md new file mode 100644 index 0000000000..8efae45446 --- /dev/null +++ b/docs/research/_synchronized-halving.md @@ -0,0 +1,196 @@ +--- +title: "Token Halvings Problem and Solution" +--- + +# Token Halvings Problem and Solution + +Authors: [Maciej Kula](https://github.com/mcjkula), [Michael Trestman](https://github.com/MichaelTrestman) and [Spacetime_tao](https://x.com/Spacetime_tao) + +This page explains the motivation for synchronizing ALPHA [emission](#emission) halvings with the global [TAO](#tao-τ) halving schedule, in plain language without requiring any math. + +In Bittensor's Dynamic TAO (dTAO) system, each [subnet](../resources/glossary.md#subnet) has its own token, referred to as its ALPHA (α), which represents [stake](../resources/glossary.md#stake) in the subnet and powers commodity validation according to [Yuma Consensus](../learn/yuma-consensus). While this creates a powerful market-driven allocation system, the current design uses independent halving schedules that create unintended asymmetries over time, disadvantaging later subnet cohorts. + +For formal derivations, see the [white paper](https://github.com/mcjkula/papers/blob/main/dtao-halving-synchronization-2025-v1.pdf) by Maciej Kula. + +See also: [Token Halvings Problem and Solution: Frequently asked questions (FAQ)](./halvings-problem.md). + +## 1) Background: Current Token Emissions Halving Schedules + +### Market-driven emissions + +In Bittensor, each subnet has its own token, known as its ALPHA (α) currency. TAO-holders can trade TAO for ALPHA-tokens, and vice-versa. This internal currency marketplace is historically known as Dynamic TAO (dTAO), in contrast to the initial iteration of Bittensor, in which all subnets shared a single 'static' TAO currency. + +So that users can trade TAO (τ) for any subnet's ALPHA token, and vice versa, on demand, each subnet maintains reserves of both tokens, and adjusts the price as needed. This is a customized application of the [Uniswap](https://en.wikipedia.org/wiki/Uniswap) AMM pattern. + +Users stake by putting TAO into a subnet's reserve and taking ALPHA; they unstake (sell) by putting ALPHA in and taking TAO out. The price is simply the ratio of TAO per ALPHA in the subnet's reserve pools. + +### How the tokens flow + +The dTAO emissions process involves a threefold token injection for each subnet, which occurs each block. Over time, emissions halvings will change the rate of these token injections. + +1. **τ_in (TAO injection)**: New TAO is injected into every subnet's AMM reserve each [block](../resources/glossary.md#block). This allocation is distributed across subnets based on their relative prices, with [EMA](../resources/glossary.md#exponential-moving-average-ema) smoothing to prevent manipulation. TAO injections shrink over time following the global TAO [halving schedule](./halvings-problem.md). + +2. **α_in (ALPHA injection)**: ALPHA tokens are minted directly into each subnet's AMM reserve to maintain balanced liquidity on both sides of the pool. This injection is capped by the same global TAO halving schedule as τ_in, ensuring they shrink together proportionally. + +3. **α_out (ALPHA outbound emissions)**: ALPHA tokens bound for distribution to network participants (miners, validators, and stakers) accumulate each block throughout an epoch, before being emitted to participants at the epoch's conclusion. Unlike the injections above, **ALPHA emissions** follow each subnet's own independent ALPHA halving schedule. + +**Critical insight**: The first two flows (τ_in and α_in) are synchronized to the global TAO clock, while the third flow (α_out) runs on each subnet's local clock. This timing mismatch is the root cause of the asymmetries described below. + + +### Why α_in must follow TAO halvings + +The synchronization between TAO and ALPHA injections is essential for market stability. If global TAO [issuance](../resources/glossary.md#issuance) halves but ALPHA injection (α_in) does not, each subnet's AMM pool would suddenly receive proportionally more ALPHA tokens per TAO token. This would cause prices to drop by 50%, since it's now double the amount of α_in per τ_in as before. + +To maintain stable exchange rates and prevent artificial price shocks, α_in must be locked to TAO's global halving schedule. This ensures that both sides of the AMM pool shrink proportionally, preserving price relationships across halving events. Without this synchronization, the exchange rate would be pushed by the chain to be 50% of the emission rate, due to the ratio of the emissions changing in favor of alpha. + +ALPHA emissions to participants (α_out) remain on each subnet's independent local halving schedule, while injections follow the global TAO schedule. While synchronizing injections (τ_in and α_in) stabilizes markets, this 'semi-synchronization' creates unintended downstream consequences. This timing split—α_in synchronized globally, α_out running locally—creates a growing imbalance between "ALPHA in AMM pools" versus "ALPHA in participant wallets." This imbalance is the mathematical root cause of all four distortions described below. + +## 2) The problem + +The fundamental issue emerges from the timing mismatch between global and local halving schedules. When ALPHA injections (α_in) halve according to TAO's global schedule but ALPHA emissions (α_out) continue on each subnet's independent schedule, the ratio between "ALPHA in AMM pools" versus "ALPHA held by participants" shifts at every global halving event. + +This single mathematical drift creates several distinct but related distortions that systematically disadvantage later subnet cohorts: + +### 2.1 Halving "speed‑up" (interval compression) + +**The mechanism**: TAO halvings slow down ALPHA halvings by reducing the mining rate while keeping the threshold constant. However, when an ALPHA halving occurs, it halves the threshold while reducing the minting rate by less than 50%, causing the next ALPHA halving to happen faster (compressed intervals). This compression becomes stronger as ALPHA injections outweigh ALPHA emissions. + +**Real impact**: A subnet that initially had 2-year halving intervals might see this compress to 18 months, then 12 months, and eventually approach a "singularity" where halvings occur nearly every block. +ALPHA halvings will compress so severely that no more incentives/emissions would be distributed in ~10 years instead of the intended ~60 years. + +### 2.2 Liquidity impact on AMMs + +**The mechanism**: As ALPHA emissions (α_out) increasingly dominate relative to ALPHA injections (α_in), the AMM pools receive proportionally less liquidity while participants hold proportionally more tokens. This changes the fundamental dynamics of trading. + +**Cohort disadvantage**: For subnets created after multiple TAO halvings, the same selling pressure from participants removes a much larger fraction of the pool's TAO reserves compared to earlier subnet cohorts. This is because later subnets have smaller injection rates but the same emission rates. + +**Practical impact**: +- **Early subnets** (created before TAO halvings): Selling 10% of rewards might cause 3% [slippage](../resources/glossary.md#slippage) +- **Later subnets** (created after multiple halvings): The same 10% sell might cause 15-20% slippage + +This makes it progressively harder for newer subnets to maintain healthy liquidity and stable prices, even when participant behavior is identical across cohorts. + +### 2.3 Slower root‑proportion decline + +**Background**: The [Root Subnet](../resources/glossary.md#root-subnetsubnet-zero) (Subnet Zero) provides a mechanism for TAO holders to stake in a subnet-agnostic way. Root's influence in any given subnet depends on the total TAO staked there, scaled by the global [TAO‑weight](../resources/glossary.md#tao-weight) parameter (γ, currently 0.18). + +**The mechanism**: Root's proportional influence should decline as each subnet's ALPHA supply grows through emissions. However, after TAO halvings, ALPHA injections (α_in) slow down while the TAO-weight parameter (γ) remains constant. This means new ALPHA supply grows more slowly, allowing Root to maintain disproportionate influence for longer periods. + +**Cohort impact**: +- **Early subnets**: Root's influence declined predictably as ALPHA supply grew +- **Later subnets**: Root maintains higher influence for extended periods due to slower ALPHA supply growth + +**Solution**: Scale the TAO-weight parameter with each TAO halving (e.g., 0.18 → 0.09 → 0.045 → …). This would keep Root's effective power declining in sync with the overall issuance scale, preserving consistent dilution dynamics across all epochs. + +### 2.4 Disadvantageous liquidation + +**Subnet deregistration context**: Subnets can be deregistered based on their relative performance (currently the lowest EMA subnet among all subnets). When this occurs, the AMM pool is dissolved, and all ALPHA holders redeem their tokens against the pool's remaining TAO reserves. + +**Two critical prices**: +- **Spot price**: The current market rate offered by the AMM (TAO reserves ÷ ALPHA reserves) +- **Liquidation price**: The redemption value if the subnet gets deregistered (TAO reserves ÷ total outstanding ALPHA held by users) + +**Alpha Distribution Ratio ([ADR](../resources/glossary.md#adr-alpha-distribution-ratio))**: This metric compares ALPHA tokens held by participants versus ALPHA tokens remaining in the AMM pool. When injection and emission clocks are misaligned, emissions (α_out) tend to outpace injections (α_in), pushing more ALPHA into participant wallets and driving ADR above 1. A higher ADR means more tokens are in circulation relative to what's in the pool, which affects liquidation dynamics. + +**The liquidation [haircut](./halvings-problem#haircut-h)**: When ADR > 1, the liquidation price falls below the spot price. This creates a built-in "haircut" risk where ALPHA holders recover less TAO than their tokens' current market value suggests. + +**What is a haircut?** A haircut is the discount between what you expect to receive (based on current market price) and what you actually receive during liquidation. For example, if your ALPHA tokens are worth 100 TAO at market price but you only receive 75 TAO during subnet liquidation, you've suffered a 25% haircut. + +**Cohort impact examples**: +- **Early subnets** (ADR ≈ 1): Liquidation price matches spot price — no haircut +- **Later subnets** (ADR >> 1): Liquidation price significantly below spot — substantial haircut risk + +This asymmetry makes staking in later subnet cohorts fundamentally riskier, even when the underlying subnet performance is identical. + + + +### 2.5 One root cause + +Despite appearing as four separate problems, all of the above distortions stem from a single mathematical source: **timing asynchrony between global and local halving schedules**. + +**The fundamental split**: +- **Global TAO clock** governs TAO injections (τ_in) and ALPHA injections (α_in) +- **Local subnet clocks** govern ALPHA emissions (α_out) to participants + +**The compounding effect**: At each global TAO halving, the gap between these two timing systems widens. This changes the fundamental ratio between "tokens injected into pools" versus "tokens emitted to participants," and all four distortions flow mathematically from this shifting ratio. + +**Why it gets worse over time**: The longer the Bittensor network operates, the more TAO halvings occur, and the more severe these asymmetries become. Critically, no subnet truly benefits in the long term. + +## 3) Toward a Solution: Exploring a synchronized design + +### 3.1 Core change — one clock for both + +The proposed solution directly addresses the root cause by eliminating the timing mismatch: + +**Synchronization principle**: Set every subnet's ALPHA emissions (α_out) to halve on the same global blocks as TAO halvings, rather than following independent local schedules. + +**Unified timing**: Now all three flows—TAO injections (τ_in), ALPHA injections (α_in), and ALPHA emissions (α_out)—shrink together proportionally at each global halving event. + +### 3.2 Immediate benefits + +Synchronization eliminates all four distortions at their mathematical source: + + +1. **Cohort-invariant liquidity**: Selling a fixed fraction of rewards produces identical AMM slippage impact across all subnet cohorts, regardless of when they were created. + +2. **Predictable root dynamics**: Root Subnet influence follows a stable dilution trajectory when the TAO-weight parameter (γ) is scaled alongside issuance (e.g., 0.18 → 0.09 → 0.045). + +3. **Elimination of liquidation haircuts**: The liquidation price matches the spot price for all cohorts (ADR = 1), removing built-in disadvantages for later subnets. + +4. **Stable emission schedule**: ALPHA emissions would halve with TAO every 4 years, eliminating the problematic independent ALPHA halving schedule entirely. + +### 3.3 Key implications and trade-offs + +While synchronization solves the core asymmetry problems, it introduces some changes to the current system: + +#### Supply implications +**Reduced maximum supply for some cohorts**: The current system's interval compression effectively accelerates some subnets beyond their intended pace. Synchronization removes this artificial acceleration, resulting in lower total ALPHA supply for cohorts that would have benefited from compression. Hence, nobody truly benefits. + +**Predictable supply curves**: Each subnet's maximum ALPHA supply becomes calculable based on its registration timing relative to the global TAO supply, creating transparent and predictable tokenomics. + +#### Long-term considerations + +**Emission endpoint**: Once halvings reduce per-block rewards below the smallest unit (RAO = 10⁻⁹ TAO), minting would naturally stop unless token precision is increased. + +**Two tail options**: +1. **Hard-stop tail**: Emissions end at the final discrete halving when rewards reach the RAO floor. Simple and finite, but creates a discontinuous endpoint. This approach would also require increasing the TAO supply above 21 million, which may not be desirable. +2. **Zeno-halving tail**: Increase token precision (e.g., from 9 to 18 decimal places) so halvings can continue smoothly below the current minimum unit. Rewards asymptotically approach zero without ever stopping, maintaining the same finite total supply with smoother mathematical properties. + +#### Parameter adjustments + +**TAO-weight scaling**: The TAO-weight parameter (γ) should be halved at each TAO halving (0.18 → 0.09 → 0.045 → …) to keep Root Subnet influence properly aligned with the shrinking issuance scale across all epochs. + +## 5) Further considerations + +### Timing urgency + +The asymmetries described above begin manifesting immediately after the first TAO halving and compound with each subsequent halving. Early implementation preserves fairness across subnet cohorts, while delayed implementation creates permanent advantages for early subnets and disadvantages for later ones. + +### Transition approach + +Several implementation strategies could be considered: +- **Immediate synchronization** (The authors' recommended course of action): All existing subnets switch to the global halving schedule. This levels the playing field and prevents gaming opportunities that could arise from grandfathering or opt-in approaches. +- **Grandfathering**: Existing subnets continue on local schedules, new subnets use global schedule. One implication of this approach is that grandfathered subnets would reach their supply cap in ~10 years instead of ~60 years, while still benefiting from liquidity and liquidation advantages. +- **Opt-in transition**: Subnet creators choose between current and synchronized models + +### Governance considerations + +The proposed change affects fundamental tokenomics and requires broad community consensus. The mathematical analysis provides objective evidence of the problems, but implementation decisions involve balancing current subnet owner interests against long-term network fairness and sustainability. + +## 6) Conclusion + +Dynamic TAO represents a significant advancement over manual emission allocation through validator voting, introducing market-driven price discovery to subnet resource allocation. However, the current system's split halving schedules create unintended mathematical asymmetries that systematically disadvantage later subnet cohorts. + +The authors believe that this problem requires immediate scrutiny and open discussion from the Bittensor community, and that an adequate solution likely requires a change to the logic of Bittensor's emissions system. We believe that this type of decisions should be made with open discussion, and a solution chosen that has broad acceptance from the Bittensor community, and we hope this paper can serve those ends. + +**The core insight**: All four distortions—interval compression, liquidity disadvantages, root-share dynamics, and liquidation haircuts—stem from a single source: the timing mismatch between global TAO halvings and local ALPHA halvings. + +**The proposed solution**: Synchronizing ALPHA emissions with the global TAO halving schedule eliminates these asymmetries at their mathematical root, creating: +- Consistent halving intervals across all epochs +- Cohort-invariant trading dynamics +- Predictable Root Subnet influence patterns +- Elimination of liquidation disadvantages + +**Implementation trade-offs**: While synchronization solves the asymmetry problems, it requires accepting different maximum ALPHA supplies for some cohorts and implementing either hard-stop or Zeno-style emission tails. Scaling the TAO-weight parameter with each halving ensures consistent root dynamics. + +**The result**: A mathematically cleaner system with fairer outcomes for every subnet cohort, predictable tokenomics for builders and users, and elimination of timing-based advantages that have nothing to do with subnet performance or value creation. diff --git a/docs/bittensor-rel-notes.md b/docs/resources/bittensor-rel-notes.md similarity index 100% rename from docs/bittensor-rel-notes.md rename to docs/resources/bittensor-rel-notes.md diff --git a/docs/resources/community-links.md b/docs/resources/community-links.md new file mode 100644 index 0000000000..7719a84bc7 --- /dev/null +++ b/docs/resources/community-links.md @@ -0,0 +1,35 @@ +--- +title: "Bittensor Community Links" +--- + +# Bittensor Community Links + +Welcome to the Bittensor ecosystem! This page provides links to essential community tools and resources to help you navigate the Bittensor network. + +You can also explore Bittensor's many Subnets and find links to their websites and repositories through [our Subnet listings](https://learnbittensor.org/subnets). + +## Opentensor Foundation (OTF) + +- **Twitter**: [@opentensor](https://x.com/opentensor) - Official announcements and updates +- **Podcast**: [Novelty Search](https://www.youtube.com/@Opentensor/podcasts) - Official Opentensor Foundation podcast +- **Discord**: [Join the Bittensor Discord Server](https://discord.com/invite/bittensor) - Connect with the community, ask questions, and stay updated + + +## Block Explorers + +- **[TAO.app](https://tao.app)** - Recommended (maintained by [Latent](https://latent.to/), the team behind these docs and core contributors to the Bittensor ecosystem). Includes [Savant](https://tao.app/savant), the chain explorer AI assistant. +- **[Taostats](https://taostats.io/)** +- **[Taomarketcap](https://taomarketcap.com/)** + +## Wallet Applications + +- **[Bittensor Wallet](https://bittensor.com/wallet)** - Recommended (maintained by OTF). +- **[Other Polkadot Wallets](https://polkadot.com/get-started/wallets/)** - Multi-chain wallets capable of interacting with Bittensor. + +## Development Resources + +- **[BTCLI](https://github.com/opentensor/btcli)**, the Bittensor CLI +- The **[Bittensor SDK](https://github.com/opentensor/bittensor)** +- **[Subtensor](https://github.com/opentensor/subtensor)**, Bittensor's substrate blockchain + + diff --git a/docs/resources/glossary.md b/docs/resources/glossary.md new file mode 100644 index 0000000000..e912eb1379 --- /dev/null +++ b/docs/resources/glossary.md @@ -0,0 +1,1001 @@ +--- +title: "Glossary" +--- + +# Glossary + +## A + +### Active UID + +A UID slot that is considered active within a specific subnet, allowing the associated hotkey to participate as a subnet validator or subnet miner. + +**See also:** [Subnet Miners](../miners/), [Subnet Validators](../validators/) + +### ADR (Alpha Distribution Ratio) + +A metric that compares ALPHA tokens held by participants versus ALPHA tokens remaining in the AMM pool. ADR is calculated as the ratio of emissions to injections, measuring how much ALPHA goes to people (emissions) relative to how much is put into the pool (injections). A higher ADR means liquidation happens at a deeper discount to spot price. Under the current protocol, ADR tracks 2^(k - n), where k is the global TAO halving index and n is the subnet's ALPHA halving index. + +### Archive Node + +A type of public subtensor node that stores the entire blockchain history, allowing for full data access and querying capabilities. + +**See also:** [Subtensor Nodes](../subtensor-nodes/), [Managing Subtensor Connections](../sdk/managing-subtensor-connections.md) + +### Axon + +A module in the Bittensor API that uses the FastAPI library to create and run API servers. Axons receive incoming Synapse objects. Typically, an Axon is the entry point advertised by a subnet miner on the Bittensor blockchain, allowing subnet validators to communicate with the miner. + +**See also:** [Subnet Miners](../miners/), [Subnet Validators](../validators/) + +## B + +### Bicameral Legislature + +A two-tier legislative system comprising the Triumvirate and the Senate for proposal approval. + +**See also:** [Governance](../governance/governance.md), [Senate](../governance/senate.md) + +### Bittensor Wallet + +A digital wallet that holds the core ownership in the Bittensor network and serves as the user's identity technology underlying all operations. + +**See also:** [Wallets](../keys/wallets.md), [Working with Keys](../keys/working-with-keys.md) + +### Block + +A unit of data in the Bittensor blockchain, containing a collection of transactions and a unique identifier (block hash). A single block is processed every 12 seconds in the Bittensor blockchain. + +**See also:** [Subtensor API](../sdk/subtensor-api.md) + +### Burn cost + +This refers to the required amount of TAO to be recycled when creating a new subnet, i.e., cost of registering a new subnet. + +**See also:** [Burn cost](../subnets/create-a-subnet.md#burn-cost) + +## C + +### Coldkey + +A component of a Bittensor wallet responsible for securely storing funds and performing high-risk operations such as transfers and staking. It is encrypted on the user's device. This is analogous to a private key. + +**See also:** [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md), [Working with Keys](../keys/working-with-keys.md) + +### Coldkey-hotkey pair + +A combination of two keys, a coldkey for secure storage and high-risk operations, and a hotkey for less secure operations and network interactions. + +**See also:** [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md), [Working with Keys](../keys/working-with-keys.md) + +### Commit Reveal + +The Commit Reveal feature is designed to solve the weight-copying problem by giving would-be weight-copiers access only to stale weights. Copying stale weights should result in validators departing from consensus. + +**See also:** +- [Commit Reveal](../concepts/commit-reveal.md) +- [The Weight Copying Problem](../concepts/weight-copying-in-bittensor) + +### Consensus Score + +The consensus score is calculated as the stake-weighted median of all weights assigned to a specific neuron by validators. This creates a consensus threshold that filters out outlier weights, ensuring that only weights near the median consensus are used in final rank calculations. + +**See also:** [Yuma Consensus](../learn/yuma-consensus.md), [Consensus-Based Weights](../concepts/consensus-based-weights.md) + +#### Mathematical Definition: + +For each neuron $j$, the consensus score $C_j$ is calculated as: + +$$ +C_j = \text{weighted\_median}(\{w_{ij} \mid i \in \text{validators}\}, \{s_i \mid i \in \text{validators}\}, \kappa) +$$ + +Where: + +- $w_{ij}$ is the weight assigned by validator $i$ to neuron $j$ +- $s_i$ is the stake of validator $i$ +- $\kappa$ is the consensus majority ratio (typically 51%) +- $\text{weighted\_median}$ is the stake-weighted median function + +Calculation Process: + +1. **Weight collection**: Gather all weights assigned to each neuron by validators +2. **Stake weighting**: Apply stake weights to validator opinions +3. **Median calculation**: Find stake-weighted median using κ parameter (typically 51%) +4. **Threshold establishment**: Consensus score becomes clipping threshold for weights + +Properties and Interpretation: + +- **Range**: [0, 1] normalized values +- **High Consensus**: Values close to 1 indicate strong validator agreement +- **Low Consensus**: Values close to 0 indicate weak validator agreement +- **Outlier Detection**: Weights below consensus score are clipped to 0 + +Network Security Properties: + +- **Anti-Manipulation**: Consensus filtering prevents weight manipulation by outliers +- **Stake-Weighted**: Higher stake validators have more influence in consensus +- **Dynamic Threshold**: Consensus adapts to changing network conditions +- **Majority Rule**: κ parameter controls consensus strictness (typically 51%) + +#### Relationship to Other Metrics + +**Consensus vs Trust:** + +- **Consensus**: Stake-weighted median of weights (consensus threshold) +- **Trust**: Ratio of final rank to pre-rank (consensus alignment impact) +- **Relationship**: Consensus determines weight clipping, Trust measures the impact + +**Consensus vs Ranks:** + +- **Consensus**: Threshold for weight filtering +- **Ranks**: Final performance scores after consensus filtering +- **Relationship**: Consensus influences rank calculation through weight clipping + +**Consensus vs Validator Trust:** + +- **Consensus**: Per-neuron consensus thresholds +- **Validator Trust**: Sum of clipped weights set by each validator +- **Relationship**: Validator trust measures validator influence in consensus + +**Source**: + +- [`bittensor/bittensor/core/metagraph.py:360-372`](https://github.com/opentensor/bittensor/blob/main/bittensor/core/metagraph.py#L360-372) +- [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:595`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L595) + +## D + +### Delegate + +A subnet validator that receives staked TAO tokens from delegators and performs validation tasks in one or more subnets. + +**See also:** [Delegation](../staking-and-delegation/delegation.md), [Managing Stake with btcli](../staking-and-delegation/managing-stake-btcli.md) + +### Delegate Stake + +The amount of TAO staked by the delegate themselves. + +**See also:** [Managing Stake with btcli](../staking-and-delegation/managing-stake-btcli.md), [Managing Stake with SDK](../staking-and-delegation/managing-stake-sdk.md) + +### Delegation + +Also known as staking, delegating TAO to a validator (who is thereby the delegate), increases the validator's stake and secure a validator permit. + +**See also:** [Delegation](../staking-and-delegation/delegation.md), [Managing Stake with btcli](../staking-and-delegation/managing-stake-btcli.md) + +### Dendrite + +A client instance used by subnet validators and subnet miners to transmit information to axons on subnet miners and subnet validators. Dendrites communicate with axons using the server-client (Axon-dendrite) protocol. + +**See also:** [Subnet Miners](../miners/), [Subnet Validators](../validators/) + +### Deregistration + +The process of removing a subnet miner or a subnet validator from the subnet due to poor performance. + +**See also:** [Miner Deregistration](../miners/#miner-deregistration), [Subnet Miners](../miners/) + + +### Drand/time-lock encryption + +[Drand](https://drand.love)) is a distributed randomness beacon network that provides publicly verifiable, unpredictable, and unbiased random numbers. It is operated by the [League of Entropy](https://drand.love/league-of-entropy/), a consortium of independent organizations running Drand nodes. + +Drand provides **time-lock encryption**, a cryptographic technique that encrypts data so that it can only be decrypted *after a specific time has passed*. Drand provides this capability by regularly producing randomness "pulses" at fixed intervals. Data encrypted for a future Drand round cannot be decrypted—even by the person who encrypted it—until that round's randomness is published. + +Key properties that make Drand suitable for applications in Bittensor, such as [Commit Reveal](#commit-reveal): +- **Decentralized**: No single entity controls the randomness generation +- **Verifiable**: Anyone can verify that randomness was generated correctly +- **Predictable timing**: Pulses are produced at regular intervals +- **Industry adoption**: Used by multiple blockchain and cryptographic protocols +- **Open source**: Fully transparent implementation + +Learn more: +- [Drand Time-Lock Encryption documentation](https://drand.love/docs/timelock-encryption/) +- [Commit Reveal](../concepts/commit-reveal) + +## E + +### EdDSA Cryptographic Keypairs + +A cryptographic algorithm used to generate public and private key pairs for coldkeys and hotkeys in the Bittensor wallet. + +**See also:** [Working with Keys](../keys/working-with-keys.md), [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md) + +### Effective stake + +The total staked TAO amount of a delegate, including their own TAO tokens and those delegated by nominators. + +**See also:** [Managing Stake with btcli](../staking-and-delegation/managing-stake-btcli.md), [Managing Stake with SDK](../staking-and-delegation/managing-stake-sdk.md) + +### Emission + +Every block, currency is injected into each subnet in Bittensor, and every tempo (or 360 blocks), it is extracted by participants (miners, validators, stakers, and subnet creators). + +Emission is this process of generating and allocating currency to participants. The amount allocated to a given participant over some duration of time is also often referred to as 'their emissions' for the period. + +Emissions are protected from manipulation through [Exponential Moving Average (EMA)](#exponential-moving-average-ema) mechanisms that smooth both validator-miner bond evolution and subnet price effects. + +**See also:** [Emissions](../learn/emissions.md), [Exponential Moving Average (EMA)](#exponential-moving-average-ema) + +### Encrypting the Hotkey + +An optional security measure for the hotkey. + +**See also:** [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md), [Working with Keys](../keys/working-with-keys.md) + +### Exponential Moving Average (EMA) + +A weighted moving average that prioritizes recent observations while exponentially decreasing the weight of older data points. In Bittensor, EMA is used in two critical stability mechanisms: + +1. **Validator-Miner Bond Smoothing**: Smooths the evolution of bonds between validators and miners over time, rewarding early discovery while preventing abrupt manipulation attempts. Has two modes: + + - **Basic Mode**: Single α ≈ 0.1 (~7-22 blocks for significant changes) + - **Liquid Alpha Mode**: Dynamic α range 0.7-0.9 based on consensus alignment (~1-13 blocks depending on consensus) + +2. **Subnet Price Emission Smoothing**: Protects emissions from price manipulation by extremely slowly incorporating price changes into emission calculations (α ≈ 0.000003, ~30 days for 50% adjustment) + +**Formula**: `EMA(t) = α × Current_Value + (1 - α) × EMA(t-1)` + +**Key Properties**: + +- Lower α = slower adaptation, higher stability +- Higher α = faster adaptation, lower stability +- Bittensor prioritizes stability with conservative α values + +**See also:** [Understanding Exponential Moving Averages](../learn/ema.md), [Consensus-based Weights](../concepts/consensus-based-weights.md), [Validator-Miner Bonds](#validator-miner-bonds), [Emission](#emission) + +### External Wallet + +A Bittensor wallet created through the Bittensor website or using a tool like [subkey](https://docs.substrate.io/reference/command-line-tools/subkey/), allowing users to use TAO without installing Bittensor. + +**See also:** [Wallets](../keys/wallets.md), [Installation](../getting-started/installation.md) + +## F + +### Fast blocks + +A development-only configuration that accelerates block production to 250ms intervals, enabling rapid local testing and immediate execution of on-chain operations. + +**See also:** [Create a local instance](../local-build/deploy.md?local-chain=docker#2-run-the-container) + +## H + +### Hotkey + +A component of a Bittensor wallet responsible for less secure operations such as signing messages into the network, secure a UID slot in a subnet, running subnet miners and subnet validators in a subnet. It can be encrypted or unencrypted, but is unencrypted by default. The terms "account" and "hotkey" are used synonymously. + +**See also:** [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md), [Working with Keys](../keys/working-with-keys.md) + +### Hotkey-Coldkey Pair + +Authentication mechanism for delegates and nominators and for delegates participating in the Senate. + +**See also:** [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md), [Working with Keys](../keys/working-with-keys.md) + +## I + +### Immunity Period + +A grace period granted to newly registered neurons during which they are protected from deregistration due to poor performance. The immunity period allows new miners and validators time to establish themselves and improve their performance before becoming eligible for pruning. The default period being is 4096 blocks (~13.7 hours), but can be configured by the subnet creator. + +**See also:** [Miner Deregistration](../miners/#miner-deregistration), [Validator Deregistration](../validators/index.md#validator-deregistration), [Subnet Hyperparameters](../subnets/subnet-hyperparameters.md#immunityperiod) + +### Incentives + +A portion of the TAO emission received by the subnet miners when they provide valuable services and compete for UID slots in a subnet. + +**See also:** [Emissions](../learn/emissions.md), [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism.md) + +### Incentive Mechanism + +A system that drives the behavior of subnet miners and governs consensus among subnet validators in a Bittensor subnet. Each subnet has one or more incentive mechanisms, which should be designed carefully to promote desired behaviors and penalize undesired ones. When multiple incentive mechanisms are used, each operates independently with separate bond pools for Yuma Consensus calculations, allowing subnet creators to distribute emissions across different types of work or evaluation criteria. + +**See also:** [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism.md), [Multiple Incentive Mechanisms Within Subnets](../subnets/understanding-multiple-mech-subnets), [Understanding Subnets](../subnets/understanding-subnets.md) + +### Issuance + +The total amount of TAO circulating in the Bittensor network. Includes TAO that is help in wallets and subnet liquidity pools, as well as TAO that is locked as subnet registration fees. + +This can be viewed on Bittensor explorers such as [TAO.app](https://tao.app) and [TAOstats](https://taostats.io). + +To query it directly from the change, see: [Subtensor Storage Query Example: Total Issuance](../subtensor-nodes/subtensor-storage-query-examples.md#123-totalissuance) + +See also: [Recycling, burning, and locking](#recycling-and-burning) + +## L + +### Lite Node + +A type of public subtensor node that stores limited blockchain data and relies on archive nodes for full historical data. + +**See also:** [Subtensor Nodes](../subtensor-nodes/), [Managing Subtensor Connections](../sdk/managing-subtensor-connections.md) + +### Local Blockchain + +A private blockchain used for developing and testing subnet incentive mechanisms. A local blockchain is not public and is isolated from any Bittensor network. + +**See also:** [Local Build](../local-build/deploy), [Create a Subnet](../local-build/create-subnet.md) + +### Local Wallet + +A Bittensor wallet created on the user's machine, requiring the installation of Bittensor. + +**See also:** [Wallets](../keys/wallets.md), [Installation](../getting-started/installation.md) + +### Loss Function + +In the context of machine learning, a mathematical function that measures the difference between the predicted output and the ground truth. In Bittensor, incentive mechanisms act as loss functions that steer subnet miners towards desirable outcomes. + +**See also:** [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism.md), [Understanding Subnets](../subnets/understanding-subnets.md) + +## M + +### Mainchain + +The primary Bittensor blockchain network, used for production purposes and connected to lite or archive nodes. + +**See also:** [Bittensor Networks](../concepts/bittensor-networks.md), [Subtensor Nodes](../subtensor-nodes/) + +### Metagraph + +A data structure that contains comprehensive information about the current state of a subnet, including detailed information on all the nodes (neurons) such as subnet validator stakes and subnet weights in the subnet. Metagraph aids in calculating emissions. + +**See:** [The Subnet Metagraph](../subnets/metagraph) + +### Multiple Incentive Mechanisms + +A feature that allows subnets to implement multiple independent evaluation systems within a single subnet. Each mechanism operates with its own bond pool for Yuma Consensus calculations, enabling subnet creators to distribute emissions across different types of work or evaluation criteria. Validators must evaluate miners separately for each mechanism, and miner performance in one mechanism does not affect their rating in another. + +**See also:** [Multiple Incentive Mechanisms Within Subnets](../subnets/understanding-multiple-mech-subnets), [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism.md) + +### Miner Deregistration + +The process of removing a poor-performing subnet miner from a UID slot, making room for a newly registered miner. + +**See also:** [Miner Deregistration](../miners/#miner-deregistration) + +### Mnemonic + +A sequence of words used to regenerate keys, in case of loss, and restore coldkeys and hotkeys in the Bittensor wallet. + +**See also:** [Handle Seed Phrase](../keys/handle-seed-phrase.md), [Working with Keys](../keys/working-with-keys.md) + +## N + +### NaCl Format + +A secure encryption format, using the [NaCl](https://nacl.cr.yp.to/) library, used for updating legacy Bittensor wallets to improve security. + +**See also:** [Working with Keys](../keys/working-with-keys.md), [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md) + +### Netuid + +A unique identifier assigned to a subnet within the Bittensor network. + +**See also:** [Understanding Subnets](../subnets/understanding-subnets.md), [Working with Subnets](../subnets/working-with-subnets.md) + +### Neuron + +The basic computing node in a Bittensor subnet, representing a node in a neural network. Neurons can be either subnet validators or subnet miners, each identified by a unique UID within their subnet and associated with a hotkey-coldkey pair for authentication and operations. + +Neurons participate in the network through axon servers (miners) and dendrite clients (validators), exchanging synapse objects to perform subnet-specific tasks. Their performance is measured through metrics like rank, trust, consensus, and incentive scores, which determine emissions and validator permits. + +**See also:** [Understanding Neurons](../learn/neurons.md), [Subnet Validators](../validators/), [Subnet Miners](../miners/), [NeuronInfo class](pathname:///python-api/html/autoapi/bittensor/core/chain_data/neuron_info/index.html) + +## N + +### Nominate + +The process of a delegate registering themselves as a candidate for others to stake their $TAO to. + +### Nominator + +Another term for a delegator. A subnet validator who nominates their own hotkey as a delegate, allowing others to delegate their TAO to the nominator's hotkey. + +### Nominator (Delegator) + +A TAO holder who delegates their stake. + +### Non-fast blocks + +A development-only configuration that adheres to Subtensor’s default 12-second block interval, simulating production timing for features like delayed subnet activation. + +**See also:** [Create a local instance](../local-build/deploy.md?local-chain=docker#2-run-the-container) + +## O + +### Objective Function + +In the context of machine learning and subnet operations, this refers to the goal that the subnet is continuously optimizing for, through its incentive mechanism. + +**See also:** [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism.md), [Understanding Subnets](../subnets/understanding-subnets.md) + +## P + +### Private Key + +A private component of the cryptographic key pair, crucial for securing and authorizing transactions and operations within the Bittensor network. + +**See also:** [Working with Keys](../keys/working-with-keys.md), [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md) + +### Proposal + +A suggestion or plan put forward by the Triumvirate for the Senate to vote on. + +**See also:** [Governance](../governance/governance.md), [Senate](../governance/senate.md) + +### Proposal hash + +A unique identifier for a proposal used in the voting process. + +**See also:** [Governance](../governance/governance.md), [Senate](../governance/senate.md) + +### Public Key + +A cryptographic key that is publicly available and used for verifying signatures, encrypting messages, and identifying accounts in the Bittensor network. This is the publicly shareable part of the cryptographic key pair associated with both the coldkey and hotkey, allowing others to securely interact with the wallet. + +**See also:** [Working with Keys](../keys/working-with-keys.md), [Coldkey-Hotkey Security](../keys/coldkey-hotkey-security.md) + +### Public Subtensor + +A publicly accessible node in the Bittensor network that can be run as a lite node or an archive node and synchronized with either the mainchain or testchain. + +**See also:** [Subtensor Nodes](../subtensor-nodes/), [Managing Subtensor Connections](../sdk/managing-subtensor-connections.md) + +## R + +### RAO + +A denomination of TAO, representing one billionth (10-9) of a TAO. + +**See also:** [Emissions](../learn/emissions.md) + +### Rank + +This metagraph property represents the final aggregate judgment of a each miner, computed by Yuma Consensus alogirithm operating over the miner-ratings submitted by a subnet's validators each tempo. The final `rank` score represent a miner's performance after any outlier weights set by validators have been removed through consensus clipping. This ensures that only weights near the median consensus are used in final calculations. + +Ranks are calculated as the stake-weighted sum of consensus-clipped weights and directly determine emissions to miners. + +**See also:** [Emissions](../learn/emissions.md), [Yuma Consensus](../learn/yuma-consensus.md), [Subnet Metagraph](../subnets/metagraph) + +**Relationship to Other Metrics:** + +- **Ranks vs Consensus**: Ranks are calculated using consensus-clipped weights +- **Ranks vs Trust**: Trust measures how much consensus clipping affected the rank +- **Ranks vs Incentive**: Ranks are normalized to become incentive values +- **Ranks vs Validator Trust**: Validator trust measures validator influence in consensus + +**Calculation Process:** + +1. **Pre-ranks**: Initial stake-weighted sum of all weights before consensus filtering +2. **Consensus calculation**: Stake-weighted median of weights per neuron (consensus threshold) +3. **Weight clipping**: Weights clipped at consensus threshold to remove outliers +4. **Final ranks**: Stake-weighted sum of clipped weights (the rank value) + +**Properties and Interpretation:** + +- **Range**: [0, 1] normalized values after final normalization +- **High Rank**: Values close to 1 indicate strong consensus-based performance +- **Low Rank**: Values close to 0 indicate weak consensus-based performance +- **Incentive Distribution**: Ranks directly determine incentive allocation to miner neurons + +**Network Security Properties:** + +- **Consensus-Based**: Ranks reflect network consensus rather than individual validator opinions +- **Outlier Protection**: Consensus clipping prevents manipulation by outlier weights +- **Stake-Weighted**: Higher stake validators have more influence in rank calculation +- **Dynamic Updates**: Ranks are recalculated every epoch based on current network state + +**Mathematical Definition:** +For each neuron $j$, the rank $R_j$ is calculated as: +$$R_j = \sum_{i \in \text{validators}} S_i \cdot \overline{W_{ij}}$$ + +Where: + +- $S_i$ is the stake of validator $i$ +- $\overline{W_{ij}}$ is the consensus-clipped weight from validator $i$ to neuron $j$ +- The sum is taken over all validators in the subnet + +**Source**: + +- [`bittensor/bittensor/core/metagraph.py:325-331`](https://github.com/opentensor/bittensor/blob/main/bittensor/core/metagraph.py#L325-331) +- [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:605`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L605) + +### Recycling and burning + +Tokens (TAO and subnet-specific alpha) can be 'removed from circulation', meaning these tokens exist in neither wallet nor liquidity pool, and cannot be transacted. This can happen in two ways: + +- When tokens are **recycled**, they are subtracted from the chain's record of token issuance (`TotalIssuance`), so effectively the same quantity of tokens can be emitted again. + +- In contrast, when tokens are **burned** they exist in no wallet and no pool and can no longer be transacted; however they are still included in the record of token issuance, so they will not be re-emitted, and in effect will forever remain as a quantity of _missing_ tokens, a difference between issuance and the effective quantity in circulation. + +#### Recycling + +Tokens are recycled in several cases in Bittensor operations: + +- **All transaction fees are recycled**: When transaction fees are collected, they are deducted from `TotalIssuance`, effectively recycling them back into the system for future emission. See [Transaction Fees in Bittensor](../learn/fees) +- **Subnet Creation fees**: When a new subnet is created, the cost is recycled, except for one TAO, which is used to initialize the subnet's TAO liquidity pool. +- **Neuron Registration fees**: When a user registers a hotkey on a subnet to participate as a miner or validator, they are charged a registration fee in TAO. Alpha tokens worth the current swap value of the fee are taken from the subnet's alpha liquidity pool and recycled. +- **Extrinsic transaction**: Users can manually recycle alpha tokens using the `recycle_alpha` extrinsic, which reduces both the user's stake and the subnet's `SubnetAlphaOut` tracker. + +#### Burning + +Subnet-specific alpha tokens are burned in several contexts: + +- **Creator emissions burning**: Alpha emissions for mining on a subnet are automatically burned if they are emitted to the hotkey with creator permissions on the subnet. This allows validators to burn some or all of the subnet's emissions to prevent token inflation (by weighting the subnet creator hotkey). +- **Extrinsic transaction**: Alpha can be burned on demand using the `burn_alpha` Subtensor extrinsic. Unlike recycling, burning does not reduce `SubnetAlphaOut`. +- **Root Subnet automated burning**: Subnet Zero (Root Subnet) alpha tokens are burned under specific economic conditions to maintain system stability. + +### Regenerating a Key + +The process of recreating a lost or deleted coldkey or hotkey using the associated mnemonic. + +**See also:** [Handle Seed Phrase](../keys/handle-seed-phrase.md), [Working with Keys](../keys/working-with-keys.md) + +### Register + +The process of registering keys with a subnet and purchasing a UID slot. + +**See also:** [Subnet Miners](../miners/), [Subnet Validators](../validators/), [Working with Subnets](../subnets/working-with-subnets.md) + +### Root Subnet/Subnet Zero + +Subnet Zero a.k.a. the root subnet is a special subnet. No miners can register on subnet zero, and no validation work is performed. However validators can register, and $\tau$-holders can stake to those validators, as with any other subnet. This offers a mechanism for $\tau$-holders to stake $\tau$ into validators in a subnet-agnostic way. This works because the weight of a validator in a subnet includes both their share of that subnet's $\alpha$ and their share of staked TAO in Subnet Zero. + +## S + +### SS58 Encoded + +A compact representation of public keys corresponding to the wallet's coldkey and hotkey, used as wallet addresses for secure TAO transfers. + +**See also:** [Working with Keys](../keys/working-with-keys.md), [Wallets](../keys/wallets.md) + +### Slippage + +In the context of an automated market maker (AMM), slippage is the impact on the tokens acquired in a trade due to the change in price from the trade transaction itself. + +In Bittensor, each subnet's alpha token is traded on a constant product AMM. When you stake TAO to receive alpha (or unstake alpha to receive TAO), your transaction changes the token price, resulting in receiving less than the current market rate X the quantity of the token you are inputting. + +Larger transactions cause more slippage. Bittensor provides slippage protection through tolerance limits and partial execution options. + +**See:** [Understanding Pricing and Anticipating Slippage](../learn/slippage.md) + +### Senate + +A group of elected delegates formed from the top K delegate hotkeys, responsible for approving or disapproving proposals made by the Triumvirate. + +**See also:** [Senate](../governance/senate.md), [Governance](../governance/governance.md) + +### Stake + +The amount of currency tokens delegated to a validator UID in a subnet. Includes both self-stake (from the validator's own cold-key) and stake delegated from others. + +Stake determines a validator's weight in consensus as well as their emissions. + +**See also:** [Managing Stake with btcli](../staking-and-delegation/managing-stake-btcli.md), [Managing Stake with SDK](../staking-and-delegation/managing-stake-sdk.md), [Delegation](../staking-and-delegation/delegation.md) + +### Stake Weight + +The computed total stake value for a validator that determines their consensus power and emissions in a subnet. Stake weight combines a validator's alpha stake and TAO stake using the TAO weight parameter to calculate their total influence in the network. + +**See also:** [TAO Weight](#tao-weight), [Understanding Subnets](../subnets/understanding-subnets.md) + +**Mathematical Definition:** +For a validator with alpha stake $\alpha$ and TAO stake $\tau$, the stake weight $W$ is calculated as: + +$$ +W = {\alpha + \tau \ \times w_{\tau}} +$$ + +Where $w_{\tau}$ is the global TAO weight parameter (currently 0.18) + +A validator's relative influence in a subnet is calculated as: + +$$ +\text{Relative Stake Weight} = \frac{\text{Stake Weight}_i}{\sum_{v \in \text{validators}} \text{Stake Weight}_v} +$$ + +**Consensus Power:** + +- **Weight Setting**: Higher stake weight means more influence when setting weights +- **Validator Permits**: Stake weight determines eligibility for validator permits +- **Bond Formation**: Stake weight influences bond calculations and retention + +**Validator Emissions:** + +- **Relative Distribution**: Higher stake weight -> higher emission share + +**Code References:** + +- **Yuma Consensus**: [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:530`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L530) +- **Validator dividend distribution**: [`subtensor/pallets/subtensor/src/coinbase/run_coinbase.rs:165`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/coinbase/run_coinbase.rs#L165) + +### Staking + +The process of attaching TAO to a validator hotkey, i.e., locking TAO to a subnet validator's hotkey to increase their total stake and increase their consensus power and share of dividends. + +**See also:** [Managing Stake with btcli](../staking-and-delegation/managing-stake-btcli.md), [Managing Stake with SDK](../staking-and-delegation/managing-stake-sdk.md), [Delegation](../staking-and-delegation/delegation.md) + +### Subnet + +A Bittensor subnet is an incentive-based competition market that produces a specific kind of digital commodity. It consists of a community of miners that produce the commodity, and a community of validators that measures the miners' work to ensure its quality. + +**See also:** [Understanding Subnets](../subnets/understanding-subnets.md), [Working with Subnets](../subnets/working-with-subnets.md), [Create a Subnet](../subnets/create-a-subnet.md) + +### Subnet Miner + +The task-performing entity within a Bittensor subnet. A subnet miner is a type of node in a Bittensor subnet that is connected only to subnet validators. Subnet miners are isolated from the external world and communicate bidirectionally with subnet validators. A subnet miner is responsible for performing tasks given to them by the subnet validators in that subnet. + +**See also:** [Subnet Miner Documentation](../miners/) + +### Subnet Creator + +The individual or entity responsible for defining the specific digital task to be performed by subnet miners, implementing one or more incentive mechanisms, and providing sufficient documentation for participation in the subnet. Subnet creators can configure multiple incentive mechanisms to distribute emissions across different types of work or evaluation criteria. + +**See also:** [Create a Subnet](../subnets/create-a-subnet.md), [Subnet Creators btcli Guide](../subnets/subnet-creators-btcli-guide.md), [Multiple Incentive Mechanisms Within Subnets](../subnets/understanding-multiple-mech-subnets) + +### Subnet Protocol + +A unique set of rules defining interactions between subnet validators and miners, including how tasks are queried and responses are provided. + +**See also:** [Understanding Subnets](../subnets/understanding-subnets.md), [Working with Subnets](../subnets/working-with-subnets.md) + +### Subnet scoring model + +A component of an incentive mechanism that defines how subnet miners' responses are evaluated, aiming to align subnet miner behavior with the subnet's goals and user preferences. It is a mathematical object that converts miner responses into numerical scores, enabling continuous improvement and competition among miners. When multiple incentive mechanisms are used, each has its own scoring model for independent evaluation. + +**See also:** [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism.md), [Multiple Incentive Mechanisms Within Subnets](../subnets/understanding-multiple-mech-subnets), [Understanding Subnets](../subnets/understanding-subnets.md) + +### Subnet Task + +A key component of any incentive mechanism that defines the work the subnet miners will perform. The task should be chosen to maximize subnet miner effectiveness at the intended use case for the subnet. When multiple incentive mechanisms are used within a subnet, each mechanism can define different tasks for miners to perform. + +**See also:** [Understanding Subnets](../subnets/understanding-subnets.md), [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism.md), [Multiple Incentive Mechanisms Within Subnets](../subnets/understanding-multiple-mech-subnets) + +### Subnet Weights + +The importance assigned to each subnet determined by relative price among subnets and used to determine the percentage emissions to subnets. + +**See also:** [Emissions](../learn/emissions.md), [Consensus-Based Weights](../concepts/consensus-based-weights.md) + +### Subtensor + +[Subtensor](https://github.com/opentensor/subtensor) is Bittensor's layer 1 blockchain based on substrate (now PolkadotSDK). This serves Bittensor as a system of record for transactions and rankings, operates Yuma Consensus, and emits liquidity to participants to incentivize their participation in network activities. + +The Bittensor SDK offers the [`bittensor.core.subtensor`](pathname:///python-api/html/autoapi/bittensor/core/subtensor/index.html) and [`bittensor.core.async_subtensor`](pathname:///python-api/html/autoapi/bittensor/core/async_subtensor/index.html) modules to handle Subtensor blockchain interactions. + +**See also:** [Subtensor API](../sdk/subtensor-api.md), [Subtensor Nodes](../subtensor-nodes/), [Managing Subtensor Connections](../sdk/managing-subtensor-connections.md) + +### Sudo + +A privileged key for administrative actions, replaced by governance protocol for enhanced security. + +**See also:** [Governance](../governance/governance.md), [btcli Permissions](../btcli/btcli-permissions.md) + +### Synapse + +A data object used by subnet validators and subnet miners as the main vehicle to exchange information. Synapse objects are based on the BaseModel of the Pydantic data validation library. + +**See also:** [Subnet Miners](../miners/), [Subnet Validators](../validators/) + +## T + +### TAO ($\tau$) + +The cryptocurrency of the Bittensor network, used to incentivize participation in network activities (mining, validation, subnet creation and management). A single TAO is newly created (i.e., minted) every 12 seconds on the Bittensor blockchain. + +**See also:** [Emissions](../learn/emissions.md), [Wallets](../keys/wallets.md) + +### TAO Weight + +A global parameter (currently set to 0.18) that determines the relative influence of TAO stake versus alpha stake when calculating a validator's total stake weight, a critical value that influence's a validator's consensus power and emissions. + +**See also:** [Stake Weight](#stake-weight) + +### Tempo + +A 360-block period during which the Yuma Consensus calculates emissions to subnet participants based on the latest available ranking weight matrix. A single block is processed every 12 seconds, hence a 360-block tempo occurs every 4320 seconds or 72 minutes. + +**See also:** [Yuma Consensus](../learn/yuma-consensus.md), [Emissions](../learn/emissions.md) + +### Transfer + +The process of sending TAO tokens from one wallet address to another in the Bittensor network. + +**See also:** [Wallets](../keys/wallets.md), [Working with Keys](../keys/working-with-keys.md) + +### Triumvirate + +A group of three Opentensor Foundation employees responsible for creating proposals. + +**See also:** [Governance](../governance/governance.md), [Senate](../governance/senate.md) + +### Trust + +In the Yuma Consensus algorithm, trust represents how much a miner's rank was affected by consensus clipping. Trust is calculated as the ratio of final rank to pre-rank. It represents how much of the original validator support survived the consensus clipping process, providing insight into whether a neuron received controversial or outlier weight assignments. + +**See also:** [Yuma Consensus](../learn/yuma-consensus.md), [Subnet Metagraph](../subnets/metagraph) + +**Mathematical Definition:** +For each neuron $j$, the trust $T_j$ is calculated as: + +$$ +T_j = \frac{R_j}{P_j} +$$ + +Where: + +- $R_j$ is the final rank after consensus clipping +- $P_j$ is the pre-rank before consensus clipping +- The ratio indicates the proportion of original support that survived consensus filtering + +Interpretation: + +- **Range**: [0, 1] where 1.0 indicates perfect consensus alignment +- **`Trust = 1.0`**: Neuron's rank unchanged by consensus (high consensus alignment) +- **`Trust < 1.0`**: Neuron's rank reduced by consensus clipping (lower value means more reduction) +- **`Trust = 0.0`**: Neuron's rank eliminated by consensus (no consensus support) + +Calculation Process: + +1. **Pre-ranks calculation**: $P_j = \sum_{i} S_i \cdot W_{ij}$ (stake-weighted sum of all weights) +2. **Consensus filtering**: Weights clipped at consensus threshold to remove outliers +3. **Final ranks calculation**: $R_j = \sum_{i} S_i \cdot \overline{W_{ij}}$ (stake-weighted sum of clipped weights) +4. **Trust calculation**: $T_j = R_j / P_j$ (ratio of final to pre-rank) + +**Relationship to Other Metrics:** + +- **Trust vs Consensus**: Trust measures the impact of consensus filtering +- **Trust vs Ranks**: Trust is the ratio of final rank to pre-rank +- **Trust vs Validator Trust**: Trust is per-neuron, Validator Trust is per-validator +- **Trust vs Incentive**: Trust influences incentive through consensus mechanisms + +**Metric Comparison Table** + +| Metric | Purpose | Calculation | Range | Interpretation | +| ------------------- | ------------------- | ------------------------------------------- | ------ | ------------------------------------------- | +| **Consensus** | Consensus threshold | Stake-weighted median of weights per neuron | [0, 1] | Higher = stronger validator agreement | +| **Ranks** | Performance scoring | Stake-weighted sum of clipped weights | [0, 1] | Higher = better performance after consensus | +| **Trust** | Consensus alignment | Final rank / Pre-rank | [0, 1] | 1.0 = no clipping, < 1.0 = some clipping | +| **Validator Trust** | Validator influence | Sum of clipped weights per validator | [0, 1] | Higher = more consensus-aligned validator | + +**Source**: + +- [`bittensor/bittensor/core/metagraph.py:380-393`](https://github.com/opentensor/bittensor/blob/main/bittensor/core/metagraph.py#L380-393) +- [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:608`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L608) + +The relationship between these metrics creates a feedback loop: consensus determines weight clipping, which affects ranks and trust, which influences validator trust, which feeds back into future consensus calculations. This system ensures that the network rewards neurons with strong validator agreement while penalizing those with controversial or outlier weight assignments, creating a robust mechanism for maintaining network quality and security. + +## U + +### UID Slot + +A position occupied by a subnet miner or subnet validator within a subnet, identified by a unique UID. The UID is assigned to a hotkey when it is registered in a subnet, allowing the hotkey to participate as a subnet validator or subnet miner. + +**See also:** [Subnet Miners](../miners/), [Subnet Validators](../validators/), [Working with Subnets](../subnets/working-with-subnets.md) + +### Unstaking + +The process of detaching TAO from a validator hotkey. + +**See also:** [Staking/Delegation overview](../staking-and-delegation/delegation.md) + +## V + +### Validator Permit + +A boolean flag indicating whether a specific neuron has validation rights within a subnet. Validator permits are awarded to the top K neurons by stake weight and are required for setting weights and participating in consensus. + +**See also:** [VPermit](#vpermit), [Validator Requirements](../validators/index.md#requirements-for-validation), [Stake Weight](#stake-weight) + +### VPermit + +A list of subnet IDs (netuids) indicating which subnets a delegate is authorized to validate on. VPermits are delegate-level permissions that aggregate individual validator permits across multiple subnets, allowing delegates to participate in validation activities on specific subnets. + +**See also:** [Validator Permits](#validator-permit), [Delegation](../staking-and-delegation/delegation.md), [Validator Requirements](../validators/index.md#requirements-for-validation) + +### Validator + +A type of node in a subnet that creates tasks, evaluates the performance of subnet miners and sets weights based on their output. A subnet validator is connected only to subnet miners and to the external world. Subnet validators receive inputs from the external world and communicate bidirectionally with subnet miners. + +**See also:** [Subnet Validators](../validators/), [Validators btcli Guide](../validators/validators-btcli-guide.md) + +### Validator Trust + +A specialized trust metric for validator neurons that measures their influence in the consensus process. Validator trust is calculated as the sum of all clipped weights set by each validator across all neurons, indicating how much weight a validator successfully contributed to consensus. + +**See also:** [Yuma Consensus](../learn/yuma-consensus.md), [Subnet Metagraph](../subnets/metagraph.md), [Validator-Miner Bonds](#validator-miner-bonds) + +**Basic Concept:** +Validator trust specifically measures validator neurons' influence in the consensus process. It represents how much weight each validator successfully contributed to the consensus after weight clipping, providing insight into validator alignment with network consensus. + +**Mathematical Definition:** +For each validator $i$, the validator trust $T_{vi}$ is calculated as: +$$T_{vi} = \sum_{j \in \text{neurons}} \overline{W_{ij}}$$ + +Where: + +- $\overline{W_{ij}}$ is the consensus-clipped weight from validator $i$ to neuron $j$ +- The sum is taken over all neurons in the subnet +- Validator trust measures the total influence a validator has in consensus + +**Calculation Process:** + +1. **Weight setting**: Validators set weights to all neurons in the subnet +2. **Consensus calculation**: Stake-weighted median of weights per neuron (consensus threshold) +3. **Weight clipping**: Weights clipped at consensus threshold to remove outliers +4. **Validator trust calculation**: Sum of all clipped weights set by each validator + +**Properties and Interpretation:** + +- **Range**: [0, 1] normalized values +- **High Validator Trust**: Values close to 1 indicate strong consensus alignment +- **Low Validator Trust**: Values close to 0 indicate outlier weight assignments +- **Validator Influence**: Higher validator trust means more influence in consensus decisions + +**Network Security Properties:** + +- **Consensus Alignment**: Validator trust measures how well validators align with consensus +- **Outlier Detection**: Low validator trust indicates potential manipulation attempts +- **Validator Quality**: High validator trust indicates quality validation services +- **Economic Incentives**: Validator trust influences validator rewards and bond retention + +**Source**: + +- [`bittensor/bittensor/core/metagraph.py:397-409`](https://github.com/opentensor/bittensor/blob/main/bittensor/core/metagraph.py#L397-409) +- [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:600`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L600) + +**Relationship to Other Metrics:** + +- **Validator Trust vs Trust**: Validator trust is per-validator, Trust is per-neuron +- **Validator Trust vs Consensus**: Validator trust measures validator influence in consensus +- **Validator Trust vs Ranks**: Validator trust influences rank calculation through consensus +- **Validator Trust vs Bonds**: Validator trust affects bond retention and validator permits + +### Validator-Miner Bonds + +Bonds represent the "investment" a validator has made in evaluating a specific miner. This bonding mechanism uses [Exponential Moving Average (EMA)](#exponential-moving-average-ema) to smooth bond evolution over time, integral to the Yuma Consensus' design intent of incentivizing high-quality performance by miners, and honest evaluation by validators. + +**Bond Formation Process:** + +**1. Instant Bond Calculation:** +The instant bond $\Delta B_{ij}$ of validator $i$ to miner $j$ is calculated as: +$$\Delta B_{ij} = \frac{S_i \cdot \widetilde{W_{ij}}}{\sum_{k \in \mathbb{V}} S_k \cdot \widetilde{W_{kj}}}$$ + +Where: + +- $S_i$ is validator $i$'s stake +- $\widetilde{W_{ij}}$ is the bond-weight (penalty-adjusted weight) +- The denominator normalizes by the total bond-weight for miner $j$ across all validators + +**2. Bond-Weight Calculation:** +Bond-weights are penalized when validators overstate miner performance: +$$\widetilde{W_{ij}} = (1-\beta)W_{ij} + \beta\overline{W_{ij}}$$ + +Where: + +- $W_{ij}$ is the original weight set by validator $i$ for miner $j$ +- $\overline{W_{ij}}$ is the consensus-clipped weight +- $\beta$ is the bonds penalty factor (configurable hyperparameter) + +**3. Exponential Moving Average (EMA) Bonds:** +Instant bonds are smoothed over time using [EMA](#exponential-moving-average-ema) to prevent abrupt changes: +$$B_{ij}^{(t)} = \alpha \Delta B_{ij} + (1-\alpha)B_{ij}^{(t-1)}$$ + +Where $\alpha$ is the EMA smoothing factor (see [Exponential Moving Average](#exponential-moving-average-ema) for details). + +**Bond Mechanics and Design:** + +**Consensus Alignment:** + +- Validators who stay near consensus build stronger EMA bonds +- Bonds are penalized when validators overstate miner performance +- The EMA smooths out abrupt swings in validator behavior +- Bonds incentivize consistent alignment with consensus + +**Bond Retention:** + +- Neurons retain bonds only if they keep validator permits +- Bonds are cleared when neurons lose validator permits +- Bonds are stored as sparse matrices in blockchain state + +**Bond Decay:** + +- Bonds decay over time using [EMA](#exponential-moving-average-ema) with the `bonds_moving_avg` parameter +- Higher decay rates (larger α) make bonds more responsive to recent performance +- Lower decay rates (smaller α) allow bonds to persist longer + +**Economic Alignment:** + +- Bonds create long-term relationships between validators and miners +- Validators are incentivized to discover and support promising miners early +- Bond strength reflects validator confidence in miner performance + +**Dynamic Adjustment:** + +- Bonds adapt to changing network conditions and consensus +- EMA smoothing prevents exploitation of rapid bond changes +- Bonds provide stability while allowing for network evolution + +**Retrieval:** + +- Bonds can be queried via the `bonds()` method in the Subtensor API +- Metagraph includes bonds matrix accessible via `metagraph.B` property +- Bonds are included in neuron information structures + +**Related hyperparameters:** + +- `bonds_penalty`: Controls penalty for out-of-consensus weights (0-65535) +- `bonds_moving_avg`: Controls bond decay rate (typically 900,000) +- `liquid_alpha_enabled`: Enables dynamic alpha adjustment for bonds + +**Validator Permits:** + +- Bonds are retained only by neurons with validator permits +- Loss of validator permit clears all bonds for that neuron +- Bonds align with permit retention for economic security + +**Emission Distribution:** + +- Bonds directly determine validator emission shares +- Strong bonds lead to higher validator rewards +- Bonds create market-based incentive alignment + +**Code References:** + +- [Bond calculation in epoch execution]https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs:631) +- [EMA bond computation]https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/math.rs:1475) +- [Bonds API method]https://github.com/opentensor/subtensor/blob/main/bittensor/core/async_subtensor.py:931) +- [Bonds storage definition]https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/lib.rs:1560) + +**See also:** [Yuma Consensus](../learn/yuma-consensus), [Emissions](../learn/emissions) + +### Validator Take % + +The percentage of emissions a validator takes, of the portion that depends on delegated stake (not including their emissions in proportion to their own self-stake), before the remainder is extracted back to the stakers. + +Effectively, this represents the fee percentage that validators charge delegators for validation services. + +**See also:** [Emissions](../learn/emissions.md) + +## W + +### Wallet Address + +A unique identifier derived from the public key, used as a destination for sending and receiving TAO tokens in the Bittensor network. + +**See also:** [Wallets](../keys/wallets.md), [Working with Keys](../keys/working-with-keys.md) + +### Wallet Location + +The directory path where the generated Bittensor wallets are stored locally on the user's machine. + +**See also:** [Wallets](../keys/wallets.md), [Installation](../getting-started/installation.md) + +### Weight Copying + +A free-riding exploit possible for validators, which can be guarded against using Commit Reveal. + + + +### Weight Matrix + +A matrix formed from the ranking weight vectors of all subnet validators in a subnet, used as input for the Yuma Consensus module to calculate emissions to that subnet. When multiple incentive mechanisms are used, each mechanism has its own weight matrix for independent consensus calculations. + +**See also:** [Yuma Consensus](../learn/yuma-consensus.md), [Consensus-Based Weights](../concepts/consensus-based-weights.md), [Multiple Incentive Mechanisms Within Subnets](../subnets/understanding-multiple-mech-subnets) + +### Weight Vector + +A vector maintained by each subnet validator, with each element representing the weight assigned to a subnet miner based on its performance. When multiple incentive mechanisms are used, validators maintain separate weight vectors for each mechanism. + +The ranking weight vectors for each subnet are transmitted to the blockchain, where they combine to form the [weight matrix](#weight-matrix) (or matrices when multiple mechanisms are used) that is input for Yuma Consensus. + +**See also:** [Consensus-Based Weights](../concepts/consensus-based-weights.md), [Yuma Consensus](../learn/yuma-consensus.md), [Multiple Incentive Mechanisms Within Subnets](../subnets/understanding-multiple-mech-subnets) + +## Y + +### Yuma Consensus + +The consensus mechanism in the Bittensor blockchain that computes emissions to participants. + +**See also:** [Yuma Consensus](../learn/yuma-consensus.md) diff --git a/docs/resources/media-assets.md b/docs/resources/media-assets.md new file mode 100644 index 0000000000..8b5adb5f6e --- /dev/null +++ b/docs/resources/media-assets.md @@ -0,0 +1,11 @@ +--- +title: "Media Assets" +--- + +# Media Assets + +Download the Bittensor media assets from the below location: + +**Location**: https://github.com/latent-to/developer-docs/tree/main/static/bittensor-media-assets + +**Description**: A zip file (29 MB) containing Bittensor TAO symbol, monogram, logotype, supporting elements and a Bittensor brand guidelines PDF. diff --git a/docs/questions-and-answers.md b/docs/resources/questions-and-answers.md similarity index 86% rename from docs/questions-and-answers.md rename to docs/resources/questions-and-answers.md index ff1772f9bd..d315543b97 100644 --- a/docs/questions-and-answers.md +++ b/docs/resources/questions-and-answers.md @@ -1,7 +1,8 @@ --- title: "Frequently asked questions (FAQ)" -hide_table_of_contents: false +hide_table_of_contents: false --- + import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; @@ -32,7 +33,7 @@ import { VscFileMedia } from "react-icons/vsc"; ## Where can I get answers to my questions about Dynamic TAO? -This [Dynamic TAO FAQ](./dynamic-tao/dtao-faq). +This [Dynamic TAO FAQ](../dynamic-tao/dtao-faq). ### Is Bittensor a blockchain or an AI platform? @@ -50,7 +51,7 @@ Anyone with the funds and technical know-how can create a subnet, or participate ### How does competition work in a subnet? -The work to be performed by miners is set by the subnet creator in the form of the subnet's incentive mechanism. The miners compete to best perform the task, submitting their work to the validators. +The work to be performed by miners is set by the subnet creator in the form of the subnet's incentive mechanism. The miners compete to best perform the task, submitting their work to the validators. The validators then rank the quality of the work done by the miners within the subnet. The aggregated scores of the validators determine the quantity of TAO emitted to each miner. @@ -58,9 +59,9 @@ At the same time, validators are also incentivized to do their best work, becaus ### What exactly is the task of a subnet miner? -The task of miners is different in each subnet. For example, subnet 1 produces LLM inference, and the miner task is to respond to a text prompt with a completion. Subnet 2 serves machine translation, and subnet 21 serves storage. +The task of miners is different in each subnet. Some subnets provide AI services like specialized inference, training, or prediction. Other provide infrastructure as a service, including storage or compute. -Browse the subnets on [TAO.app](https://tao.app) +Browse tokenomic information about the subnets on [TAO.app](https://tao.app), and learn more about the projects and services they support on the [Learnbittensor.org subnet listings](https://learnbittensor.org/subnets). ### So where does the blockchain come in? @@ -68,7 +69,7 @@ The blockchain records all the key activity of the subnets in its ledger. It als ### Do subnets talk to each other? -A new abstract base class, called `SubnetsAPI` is released in Bittensor `6.8.0` and your application can use this to enable cross subnet communication. Normally, however, if you are not using the `SubnetsAPI`, then the subtensor blockchain does not mix data from one subnet with another subnet data and a subnet does not communicate with another subnet. +A new abstract base class, called `SubnetsAPI` is released in Bittensor `6.8.0` and your application can use this to enable cross subnet communication. Normally, however, if you are not using the `SubnetsAPI`, then the subtensor blockchain does not mix data from one subnet with another subnet data and a subnet does not communicate with another subnet. :::tip See also See [Bittensor Subnets API](https://github.com/opentensor/bittensor/blob/master/README.md#bittensor-subnets-api). @@ -86,7 +87,7 @@ In Bittensor, "mining", within subnets, has nothing to do with adding blocks to Yes indeed. In Bittensor, the work of validating the blockchain is performed by the Opentensor Foundation on a Proof-of-Authority model. -### What is the incentive to be a miner or a validator, or create a subnet? +### What is the incentive to be a miner or a validator, or create a subnet? Bittensor incentivizes participation through emission of TAO. Each day, 7200 TAO are emitted into the network (one TAO every 12 seconds). @@ -96,20 +97,20 @@ The emission of TAO within each subnet is as follows: - 41% to validators - 41% to the miners -See [Emissions](./emissions.md). +See [Emissions](../learn/emissions.md). ### I don't want to create a subnet, can I just be a miner or a validator? Yes! Most participants will not create their own subnets, there are lots to choose from. -See: +See: -- [Validating in Bittensor](./validators/index.md) -- [Mining in Bittensor](./miners/index.md). +- [Validating in Bittensor](../validators/index.md) +- [Mining in Bittensor](../miners/index.md). ### Is there a central place where I can see compute requirements for mining and validating for all subnets? -Unfortunately no. Subnets are not run or managed by Opentensor Foundation, and the landscape of subnets is constantly evolving. +Unfortunately no. Subnets are not run or managed by Opentensor Foundation, and the landscape of subnets is constantly evolving. Browse the subnets at [TAO.app](https://tao.app), or on [Discord](https://discord.com/channels/799672011265015819/830068283314929684). @@ -117,4 +118,4 @@ Browse the subnets at [TAO.app](https://tao.app), or on [Discord](https://discor You can keep trying forever, but your success depends on your performance. Mining and validating in a subnet is competitive. If a miner or validator is one of the three lowest in the subnet, it may be de-registered at the end of the tempo, and have to register again. -See [miner deregistration](./miners/index.md#miner-deregistration). +See [miner deregistration](../miners/index.md#miner-deregistration). diff --git a/docs/utilities.md b/docs/resources/utilities.md similarity index 61% rename from docs/utilities.md rename to docs/resources/utilities.md index 2a0ee7900d..aca4dd7f91 100644 --- a/docs/utilities.md +++ b/docs/resources/utilities.md @@ -4,10 +4,10 @@ title: "Utilities" # Utilities -This section describes the available utility scripts. +This section describes the available utility scripts. ## bt-next-adjust-block.js -**Location**: `https://github.com/opentensor/developer-docs/tree/main/src/scripts/` +**Location**: `https://github.com/latent-to/developer-docs/tree/main/src/scripts/` -**Description**: This `bt-next-adjustment-block.js` script queries a Bittensor subnet to find out how many blocks to go before the recycle register cost is recalculated. See the script for how to install and use it. \ No newline at end of file +**Description**: This `bt-next-adjustment-block.js` script queries a Bittensor subnet to find out how many blocks to go before the recycle register cost is recalculated. See the script for how to install and use it. diff --git a/docs/scripts/README.md b/docs/scripts/README.md new file mode 100644 index 0000000000..9767ebf5df --- /dev/null +++ b/docs/scripts/README.md @@ -0,0 +1,63 @@ +# Rate Limits Checker + +A simple script to query and display rate limit values from the Bittensor network. + +## What it does + +Connects to the Bittensor Finney network and queries: + +- **Global rate limits**: Transaction limits, delegate take limits, network limits, etc. +- **Subnet-specific limits**: Serving rates, adjustment intervals, immunity periods, etc. + +## Prerequisites + +- Node.js 18.0 or higher +- Dependencies installed (run `yarn install` if needed) + +## How to run + +```bash +yarn node docs/scripts/check-rate-limits.js +``` + +> **Note**: This project uses Yarn PnP, so you must run the script with `yarn node` instead of just `node`. + +## Expected output + +``` +Connecting to Bittensor network... +✓ Connected successfully! + +GLOBAL RATE LIMITS: +================== +TxRateLimit: 1 blocks (~0h) +TxDelegateTakeRateLimit: 216000 blocks (~720h) +TxChildkeyTakeRateLimit: 216000 blocks (~720h) +NetworkRateLimit: 28800 blocks (~96h) +OwnerHyperparamRateLimit: 2 tempos +WeightsVersionKeyRateLimit: 5 blocks (~0h) +AdminFreezeWindow: 10 blocks (~0h) + +SUBNET-SPECIFIC RATE LIMITS (Subnet 1): +======================================= +ServingRateLimit: 10 blocks (~0h) +AdjustmentInterval: 112 blocks (~0.4h) +ImmunityPeriod: 7200 blocks (~24h) +WeightsSetRateLimit: 100 blocks (~0.3h) +MaxRegistrationsPerBlock: 1 registrations +TargetRegistrationsPerInterval: 2 registrations + +✓ Complete +``` + +## Troubleshooting + +**Error: Cannot find module '@polkadot/api'** + +- Make sure you've run `yarn install` first +- Use `yarn node` instead of `node` to run the script + +**Connection timeout** + +- Check your internet connection +- The script connects to `wss://entrypoint-finney.opentensor.ai:443` diff --git a/docs/scripts/check-rate-limits.js b/docs/scripts/check-rate-limits.js new file mode 100644 index 0000000000..46f3db887e --- /dev/null +++ b/docs/scripts/check-rate-limits.js @@ -0,0 +1,218 @@ +/* +SIMPLE BITENSOR RATE LIMITS CHECKER +=================================== +Queries the specific rate limit state variables mentioned in the documentation. + +Usage: node simple-rate-limits.js +*/ + +const { ApiPromise, WsProvider } = require("@polkadot/api"); + +async function checkRateLimits() { + try { + console.log("Connecting to Bittensor network..."); + const wsProvider = new WsProvider( + "wss://entrypoint-finney.opentensor.ai:443" + ); + const api = await ApiPromise.create({ provider: wsProvider }); + + console.log("✓ Connected successfully!\n"); + + const blockTimeSeconds = 12; // Bittensor blocks are ~12 seconds + + // Global rate limits + console.log("GLOBAL RATE LIMITS:"); + console.log("=================="); + + try { + const txRateLimit = await api.query.subtensorModule.txRateLimit(); + console.log( + `TxRateLimit: ${txRateLimit.toNumber()} blocks (~${ + Math.round( + ((txRateLimit.toNumber() * blockTimeSeconds) / 3600) * 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("TxRateLimit: Unable to query"); + } + + try { + const txDelegateTakeRateLimit = + await api.query.subtensorModule.txDelegateTakeRateLimit(); + console.log( + `TxDelegateTakeRateLimit: ${txDelegateTakeRateLimit.toNumber()} blocks (~${ + Math.round( + ((txDelegateTakeRateLimit.toNumber() * blockTimeSeconds) / 3600) * + 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("TxDelegateTakeRateLimit: Unable to query"); + } + + try { + const txChildkeyTakeRateLimit = + await api.query.subtensorModule.txChildkeyTakeRateLimit(); + console.log( + `TxChildkeyTakeRateLimit: ${txChildkeyTakeRateLimit.toNumber()} blocks (~${ + Math.round( + ((txChildkeyTakeRateLimit.toNumber() * blockTimeSeconds) / 3600) * + 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("TxChildkeyTakeRateLimit: Unable to query"); + } + + try { + const networkRateLimit = + await api.query.subtensorModule.networkRateLimit(); + console.log( + `NetworkRateLimit: ${networkRateLimit.toNumber()} blocks (~${ + Math.round( + ((networkRateLimit.toNumber() * blockTimeSeconds) / 3600) * 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("NetworkRateLimit: Unable to query"); + } + + try { + const ownerHyperparamRateLimit = + await api.query.subtensorModule.ownerHyperparamRateLimit(); + console.log( + `OwnerHyperparamRateLimit: ${ownerHyperparamRateLimit.toNumber()} tempos` + ); + } catch (e) { + console.log("OwnerHyperparamRateLimit: Unable to query"); + } + + try { + const weightsVersionKeyRateLimit = + await api.query.subtensorModule.weightsVersionKeyRateLimit(); + console.log( + `WeightsVersionKeyRateLimit: ${weightsVersionKeyRateLimit.toNumber()} blocks (~${ + Math.round( + ((weightsVersionKeyRateLimit.toNumber() * blockTimeSeconds) / + 3600) * + 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("WeightsVersionKeyRateLimit: Unable to query"); + } + + try { + const adminFreezeWindow = + await api.query.subtensorModule.adminFreezeWindow(); + console.log( + `AdminFreezeWindow: ${adminFreezeWindow.toNumber()} blocks (~${ + Math.round( + ((adminFreezeWindow.toNumber() * blockTimeSeconds) / 3600) * 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("AdminFreezeWindow: Unable to query"); + } + + // Subnet-specific rate limits (check subnet 1 as example) + console.log("\nSUBNET-SPECIFIC RATE LIMITS (Subnet 1):"); + console.log("======================================="); + + try { + const servingRateLimit = await api.query.subtensorModule.servingRateLimit( + 1 + ); + console.log( + `ServingRateLimit: ${servingRateLimit.toNumber()} blocks (~${ + Math.round( + ((servingRateLimit.toNumber() * blockTimeSeconds) / 3600) * 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("ServingRateLimit: Unable to query"); + } + + try { + const adjustmentInterval = + await api.query.subtensorModule.adjustmentInterval(1); + console.log( + `AdjustmentInterval: ${adjustmentInterval.toNumber()} blocks (~${ + Math.round( + ((adjustmentInterval.toNumber() * blockTimeSeconds) / 3600) * 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("AdjustmentInterval: Unable to query"); + } + + try { + const immunityPeriod = await api.query.subtensorModule.immunityPeriod(1); + console.log( + `ImmunityPeriod: ${immunityPeriod.toNumber()} blocks (~${ + Math.round( + ((immunityPeriod.toNumber() * blockTimeSeconds) / 3600) * 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("ImmunityPeriod: Unable to query"); + } + + try { + const weightsSetRateLimit = + await api.query.subtensorModule.weightsSetRateLimit(1); + console.log( + `WeightsSetRateLimit: ${weightsSetRateLimit.toNumber()} blocks (~${ + Math.round( + ((weightsSetRateLimit.toNumber() * blockTimeSeconds) / 3600) * 10 + ) / 10 + }h)` + ); + } catch (e) { + console.log("WeightsSetRateLimit: Unable to query"); + } + + try { + const maxRegistrationsPerBlock = + await api.query.subtensorModule.maxRegistrationsPerBlock(1); + console.log( + `MaxRegistrationsPerBlock: ${maxRegistrationsPerBlock.toNumber()} registrations` + ); + } catch (e) { + console.log("MaxRegistrationsPerBlock: Unable to query"); + } + + try { + const targetRegistrationsPerInterval = + await api.query.subtensorModule.targetRegistrationsPerInterval(1); + console.log( + `TargetRegistrationsPerInterval: ${targetRegistrationsPerInterval.toNumber()} registrations` + ); + } catch (e) { + console.log("TargetRegistrationsPerInterval: Unable to query"); + } + + console.log("\n✓ Complete"); + + await api.disconnect(); + process.exit(0); + } catch (error) { + console.error("Error:", error.message); + process.exit(1); + } +} + +// Run the script +checkRateLimits().catch(console.error); + +// Suppress warning messages +console.warn = () => {}; diff --git a/docs/bt-api-ref.md b/docs/sdk/bt-api-ref.md similarity index 96% rename from docs/bt-api-ref.md rename to docs/sdk/bt-api-ref.md index 44d5d6a755..9f1ffd0dd1 100644 --- a/docs/bt-api-ref.md +++ b/docs/sdk/bt-api-ref.md @@ -1,5 +1,5 @@ --- -title: "Bittensor SDK" +title: "Bittensor SDK Reference" --- import { HiAcademicCap } from "react-icons/hi2"; @@ -15,10 +15,9 @@ import { GiBrainStem } from "react-icons/gi"; import { CiWallet } from "react-icons/ci"; import { SiTrpc } from "react-icons/si"; +# Bittensor SDK Reference -# Bittensor SDK - -This section presents the Bittensor SDK reference documentation. Follow the below links to specific Python modules or [click here for SDK reference homepage](pathname:///python-api/html/autoapi/bittensor/index.html). +This section presents the Bittensor SDK reference documentation. Follow the below links to specific Python modules or [click here for SDK reference homepage](pathname:///python-api/html/autoapi/bittensor/index.html). +Full path to the `scripts/localnet.sh` file in the cloned `Subtensor` repository used to launch the local chain (including for e2e tests if the Docker image is not used). + SDK skips running e2e tests if the variable is not set (used only together with the `USE_DOCKER` variable). +### `SKIP_PULL` + +Controls whether the Docker image used for end-to-end tests should be pulled from a remote container registry (e.g. GitHub Container Registry) before the test run. +This is useful in CI pipelines where a custom image is built and should not be overwritten by a remote version. + +- When `SKIP_PULL=0` (default), the test framework runs docker pull to ensure the latest version of the image is used. +- When `SKIP_PULL=1`, the pull step is skipped. The tests will only run if the required Docker image is already available locally. diff --git a/docs/sdk/migration-guide.md b/docs/sdk/migration-guide.md new file mode 100644 index 0000000000..41f1ef7ae5 --- /dev/null +++ b/docs/sdk/migration-guide.md @@ -0,0 +1,1049 @@ +--- +title: "Bittensor SDK v10.0 Migration Guide" +--- + +# Bittensor SDK v10.0 Migration Guide + +This page documents breaking changes and new features for the Bittensor Python SDK `v10.0`. This is a major release with significant refactoring, standardization, and new functionality. + +See [Bittensor Python SDK Reference Docs](./bt-api-ref) + +## Executive Summary + +Bittensor SDK v10.0 is a **major breaking release** with significant improvements to consistency, type safety, and functionality. Key changes include: + +**Breaking Changes:** + +- **Python 3.10+ required** - Python 3.9 no longer supported ([details](#python-version-support)) +- **ExtrinsicResponse return type** - All blockchain transaction functions now return structured `ExtrinsicResponse` objects instead of `bool` or tuples ([details](#extrinsicresponse-return-type)) +- **Strict Balance type checking** - All amount parameters require `Balance` objects. ([details](#balance-handling)) +- **Parameter renames** - Consistent `_ss58` suffix for all address parameters (e.g., `hotkey` → `hotkey_ss58`) ([details](#parameter-renames)) +- **Method renames and removals** - Several methods renamed or removed for consistency ([details](#breaking-changes-method-renames)) + +**New Features:** + +- **Multiple Incentive Mechanisms** - Full SDK support for running multiple evaluation mechanisms per subnet with independent weight matrices and emissions ([details](#multiple-incentive-mechanisms-support)) +- **Root claim implementation**: Adds support for setting and managing root claims directly through the SDK +- **Crowdloan implementation**: Adds support for creating, managing, and interacting with crowdloans directly through the SDK +- **Transaction simulation** - `sim_swap()` calculates exact token yields without executing transactions ([details](#simulate-token-swaps)) +- **Fee estimation** - `get_extrinsic_fee()` estimates blockchain transaction costs before submission ([details](#estimate-transaction-fees)) +- **BlockInfo class** - Rich blockchain block information objects ([details](#blockinfo-class)) + +**Major Improvements:** + +- Standardized parameter ordering across all functions ([details](#standardized-parameters)) +- Centralized extrinsic parameters in `bittensor.core.extrinsics.params` ([details](#extrinsic-parameters-package)) +- Enhanced metagraph support for mechanism-specific queries ([details](#metagraph-changes)) +- Environment variable updates for clarity ([details](#environment-variables)) + +**Migration Required:** +See the [Migration Checklist](#migration-checklist) for step-by-step upgrade instructions. + +--- + +## Python Version Support + +**Python 3.9 is no longer supported.** The SDK now requires **Python 3.10 or higher**. + +## New Features + +### Structured Extrinsic Responses (ExtrinsicResponse) + +`ExtrinsicResponse` provides rich, structured data for both outgoing requests and incoming on-chain results. While it is a breaking change in return types, it primarily unlocks better development, testing, and debugging workflows by standardizing success flags, messages, fees, receipts, and operation-specific data in one object. + +- **Purpose**: Enables more accurate, predictable code paths and easier assertions in tests +- **What you get**: Success flag, human-readable message, network fee, application-level swap fee(s), inclusion/finalization receipts, and operation-specific data +- **Where it applies**: Returned by all functions that submit extrinsics + +See details: [ExtrinsicResponse Return Type](#extrinsicresponse-return-type) + +### Multiple Incentive Mechanisms Support + +Full SDK support for **multiple incentive mechanisms within subnets** is now implemented, a major new Subtensor blockchain feature. + +Previously referred to as "sub-subnets" during development, this feature allows subnet creators to run multiple independent evaluation mechanisms within a single subnet, each with separate weight matrices, bond pools, and emission distributions. This is a significant architectural change that enables more sophisticated subnet designs. See [Multiple Incentive Mechanisms Within Subnets](../subnets/understanding-multiple-mech-subnets) for a complete overview. + +**Key Concepts:** + +- **`mechid` (Mechanism ID)**: An integer identifying which mechanism within a subnet (0 for the first mechanism, 1 for the second, etc.). +- **Default behavior**: All methods default to `mechid=0`, so existing single-mechanism subnets work unchanged +- **Backward compatible**: Subnets with only one mechanism (the default) don't need code changes + +#### Setting Mechanism Weights: + +Validators must set weights independently for each mechanism in a subnet: + +```python +# Set weights for a specific mechanism (mechid) +response = subtensor.set_weights( + wallet, + netuid=1, + uids=[0, 1, 2], + weights=[0.5, 0.3, 0.2], + mechid=0 # Mechanism ID (default: 0) +) + +# For subnets with multiple mechanisms, set weights for each: +mechanism1_response = subtensor.set_weights(wallet, netuid=1, uids, weights1, mechid=0) +mechanism2_response = subtensor.set_weights(wallet, netuid=1, uids, weights2, mechid=1) +``` + +#### Querying Mechanism-Specific Data on the Metagraph: + +All metagraph queries now accept a `mechid` parameter: + +```python +# Get metagraph for specific mechanism +metagraph = subtensor.metagraph(netuid=1, mechid=0) + +# Get weights for specific mechanism +weights = subtensor.weights(netuid=1, mechid=0) + +# Get bonds for specific mechanism +bonds = subtensor.bonds(netuid=1, mechid=0) + +# Get timelocked weight commits for a mechanism +commits = subtensor.get_timelocked_weight_commits(netuid=1, mechid=0) +``` + +### Simulate Token Swaps + +`sim_swap()` calculates the **exact token yields** for stake or unstake operations at a given block, without actually executing the transaction. + +```python +# Simulate adding stake (TAO → Alpha) to see exact Alpha received +result = subtensor.sim_swap( + origin_netuid=0, # 0 = TAO (root) + destination_netuid=1, # Target subnet + amount=tao(100.0), +) + +print(f"TAO amount: {result.tao_amount}") +print(f"Alpha received: {result.alpha_amount}") +print(f"TAO fee: {result.tao_fee}") +print(f"Alpha fee: {result.alpha_fee}") + +# Simulate unstaking (Alpha → TAO) +result = subtensor.sim_swap( + origin_netuid=1, # Source subnet + destination_netuid=0, # 0 = TAO (root) + amount=tao(100.0), +) +``` + +### Build Extrinsic Calls + +Compose an extrinsic call without submitting it to the blockchain with `compose_call`. Useful for fee estimation and transaction preparation. + +```python +from bittensor.core.extrinsics.params import StakingParams + +# Compose a call for later submission or fee estimation +call = subtensor.compose_call( + call_module="SubtensorModule", + call_function="add_stake", + call_params=StakingParams.add_stake( + netuid=1, + hotkey_ss58=hotkey_ss58, + amount=amount + ) +) + +# Use the composed call to estimate fees (requires keypair) +fee = subtensor.get_extrinsic_fee(call, wallet.coldkeypub) +``` + +### SimSwap Fee Calculation Methods + +The SDK now provides dedicated methods for calculating swap-based fees for staking operations. These methods use the new `sim_swap()` functionality (see [New Subtensor Methods](#new-subtensor-methods)) to query the Subtensor blockchain and return precise fee calculations: + +```python +# Get fee for adding stake (staking operation) +fee = subtensor.get_stake_add_fee(amount, netuid) + +# Get fee for moving stake between subnets +fee = subtensor.get_stake_movement_fee(origin_netuid, destination_netuid, amount) + +# Get fee for removing stake (unstaking operation) +fee = subtensor.get_unstake_fee(netuid, amount) + +# All methods return Balance objects representing the fee in TAO or Alpha +``` + +**Note:** These are **application-level swap fees** (0.05% of transacted liquidity), separate from **blockchain transaction fees** (weight-based). See [Transaction Fees in Bittensor](../learn/fees) for details on both fee types. + +### Verbose Logging Control + +The `Subtensor` class now supports verbose logging to help debug interactions with the Subtensor blockchain: + +```python +# Set verbose mode for trace-level logging +subtensor = Subtensor(network="test", log_verbose=True) +# Automatically sets btlogging to TRACE level for detailed blockchain interaction logs +``` + +### BlockInfo Class + +New [`BlockInfo`](pathname:///python-api/html/autoapi/bittensor/core/types/index.html) class provides rich information about blockchain blocks, including metadata and links to block explorers. + +```python +from bittensor.core.types import BlockInfo + +# Get block information by block number +block = subtensor.get_block_info(block=12345) + +# Or get block information by block hash +block = subtensor.get_block_info(block_hash="0x1234...") + +# Access block data +print(f"Block number: {block.number}") +print(f"Block hash: {block.hash}") +print(f"Timestamp: {block.timestamp}") +print(f"Number of extrinsics: {len(block.extrinsics)}") +print(f"View on explorer: {block.explorer}") + +# Access raw header data +print(f"Parent hash: {block.header['parentHash']}") + +# Iterate through extrinsics +for extrinsic in block.extrinsics: + print(f"Extrinsic: {extrinsic}") +``` + +**BlockInfo attributes:** + +- **`number`** (int): The block number +- **`hash`** (str): The block hash +- **`timestamp`** (Optional[int]): Unix timestamp when the block was created (from `Timestamp.Now` extrinsic) +- **`header`** (dict): Raw block header data from the node RPC, including parent hash, state root, and other metadata +- **`extrinsics`** (list): List of all extrinsics (transactions) included in the block +- **`explorer`** (str): Direct link to view the block on [tao.app/](https://tao.app) block explorer + +**Use cases:** + +- Inspect transaction history and block contents +- Debug blockchain interactions +- Verify transaction inclusion in specific blocks +- Access detailed block metadata for analysis +- Link users to block explorer for visual inspection + +### Hex / SS58 Conversion + +New utility function for converting hex addresses to SS58 format: + +```python +from bittensor.utils import hex_to_ss58 + +ss58_address = hex_to_ss58(hex_string) + +from bittensor.utils import ss58_to_hex + +hex_string = ss58_to_hex(ss58_address) +``` + +**Note:** `hex_to_ss58` is an alias for `ss58_encode` from scalecodec. Similarly, `ss58_to_hex` is an alias for `ss58_decode`. + +### Development Test Framework + +New developer testing utilities provide helpers and fixtures for rapid local testing of SDK integrations and extrinsic flows. Use cases: Simulate common workflows, stub chain interactions, and write predictable tests around `ExtrinsicResponse` without a full node. + +Learn more: [`bittensor/extras/dev_framework`](https://github.com/opentensor/bittensor/tree/SDKv10/bittensor/extras/dev_framework) + +### Estimate Transaction Fees + +Query the estimated fee for submitting an extrinsic to the Subtensor blockchain before actually sending it, with ``get_extrinsic_fee()`. + +```python +# Estimate the fee for a transfer extrinsic +extrinsic = subtensor.compose_call( + call_module="Balances", + call_function="transfer_keep_alive", + call_params={ + "dest": destination_address, + "value": amount.rao + } +) +fee = subtensor.get_extrinsic_fee(extrinsic, wallet.coldkeypub) +print(f"Estimated fee: {fee}") # Returns Balance object +``` + +**Use cases:** + +- Check if wallet has sufficient balance before submitting transactions +- Display estimated costs to users +- Optimize transaction batching based on fee estimates + +See also: [Transaction Fees in Bittensor](../learn/fees) for complete fee information. + +### Parameter Validation + +Validate extrinsic parameters before submission to catch errors early, with `validate_extrinsic_params`. + +```python +# Validate parameters match the extrinsic schema +params = { + "netuid": 1, + "hotkey": hotkey_ss58, + "amount_staked": amount.rao +} + +try: + # Returns validated/corrected params or raises an exception + validated_params = subtensor.validate_extrinsic_params( + call_module="SubtensorModule", + call_function="add_stake", + call_params=params + ) + print(f"Parameters validated: {validated_params}") +except Exception as e: + print(f"Invalid parameters: {e}") +``` + +**Note:** This method returns the validated parameters (potentially with corrections) or raises an exception if validation fails. It does not return a boolean. + +### Query Commitment Data + +Get commitment metadata for a hotkey on a subnet with `get_commitment_metadata`. Previously in `bittensor.core.extrinsic.serving`, now a `Subtensor` method. + +```python +# Query commitment metadata +metadata = subtensor.get_commitment_metadata(netuid=1, hotkey_ss58="5D...") +``` + +### Query Bonds Reset + +Get the last bonds reset block for a subnet with `get_last_bonds_reset`. Previously in `bittensor.core.extrinsic.serving`, now a `Subtensor` method. + +```python +# Query when bonds were last reset (requires both netuid and hotkey_ss58) +last_reset_block = subtensor.get_last_bonds_reset(netuid=1, hotkey_ss58="5D...") +``` + +### Historical Block Data Query + +The `blocks_since_last_update` method has been improved and can now be used to query historical data from archive nodes. + +```python +# Query blocks since last update with archive node support +blocks = subtensor.blocks_since_last_update(netuid=1, uid=0) +``` + +## Breaking Changes: Method Renames + +### Subnet Methods + +```python +# ❌ Old: +netuids = subtensor.get_subnets() + +# ✅ New: +netuids = subtensor.get_all_subnets_netuid() +``` + +### Stake Methods + +```python +# ❌ Old (removed - duplicate functionality): +stake_info = subtensor.get_stake_for_coldkey(coldkey) + +# ✅ Use instead: +stake_info = subtensor.get_stake_info_for_coldkey(coldkey_ss58) +``` + +### Commitment Methods + +```python +# ❌ Old: +subtensor.commit(wallet, netuid, data) + +# ✅ New: +subtensor.set_commitment(wallet, netuid, data) + +``` + +### Serving Methods + +Functions moved from `bittensor.core.extrinsic.serving` to `Subtensor` methods: + +```python +# ❌ Old: +from bittensor.core.extrinsic.serving import get_metadata, get_last_bonds_reset +metadata = get_metadata(subtensor, netuid, hotkey) +last_reset = get_last_bonds_reset(subtensor, netuid) + +# ✅ New: +metadata = subtensor.get_commitment_metadata(netuid, hotkey_ss58) +last_reset = subtensor.get_last_bonds_reset(netuid, hotkey_ss58) +``` + +### Timelocked Weight Commits + +```python +# ❌ Old (deprecated): +commits = subtensor.get_current_weight_commit_info(netuid, mechid) +commits_v2 = subtensor.get_current_weight_commit_info_v2(netuid, mechid) + +# ✅ Use: +commits = subtensor.get_timelocked_weight_commits(netuid, mechid) +``` + +## Breaking Changes: Parameter Changes + +### Consistent Parameter Ordering + +Many methods now follow the standard order: `subtensor`, `netuid`, `hotkey_ss58`, ... + +```python +# ❌ Old: +subtensor.set_children(wallet, netuid, hotkey, children, proportions) +subtensor.move_stake(wallet, origin_hotkey, dest_hotkey, amount) + +# ✅ New: +subtensor.set_children(wallet, netuid, hotkey_ss58, children) +subtensor.move_stake(wallet, origin_netuid, origin_hotkey_ss58, destination_netuid, destination_hotkey_ss58, amount) +``` + +**Methods with reordered parameters:** + +- `add_stake_multiple` +- `set_children` +- `move_stake` +- `query_subtensor` +- `query_module` +- `query_map_subtensor` +- `query_map` +- `root_set_pending_childkey_cooldown` + +### Block Parameter Standardization + +```python +# ❌ Old: +subnets = subtensor.all_subnets(block_number=12345) + +# ✅ New: +subnets = subtensor.all_subnets(block=12345) +``` + +All `block_number` and `block_id` parameters are now consistently named `block`. + +### Get Metagraph Info Fields Parameter + +```python +# ❌ Old: +info = subtensor.get_metagraph_info(netuid, field_indices=[0, 1, 2]) + +# ✅ New: +info = subtensor.get_metagraph_info(netuid, selected_indices=[0, 1, 2]) +``` + +### Mock Parameter + +```python +# ❌ Old: +subtensor = Subtensor(network="local", _mock=True) + +# ✅ New: +subtensor = Subtensor(network="local", mock=True) +``` + +The `_mock` parameter is now public as `mock` and moved to the last position in the parameter list. + +### Async Methods Parity + +All async methods now have the same parameters as sync methods: + +```python +# New parameters added to async versions: +async_subtensor.get_subnet_validator_permits(netuid, block_hash=None, reuse_block=None) +async_subtensor.get_subnet_owner_hotkey(netuid, block_hash=None, reuse_block=None) +``` + +### Removed `reuse_block` from Sync Methods + +```python +# ❌ Old: +hotkeys = subtensor.get_owned_hotkeys(coldkey, reuse_block=True) + +# ✅ New: +hotkeys = subtensor.get_owned_hotkeys(coldkey_ss58) +``` + +The `reuse_block` parameter has been removed from sync methods for consistency. It's still available in async methods where appropriate. + +### Transfer Fee Parameter Rename + +```python +# ❌ Old: +fee = subtensor.get_transfer_fee(wallet, destination, value) + +# ✅ New: +fee = subtensor.get_transfer_fee(wallet, destination, amount) +``` + +The `value` parameter has been renamed to `amount` for consistency with other amount parameters across the SDK. + +#### Weight Setting Methods Parameter Rename + +The following weight-setting methods have renamed `max_retries` to `max_attempts`: + +```python +# ❌ Old: +subtensor.commit_weights(wallet, netuid, uids, weights, max_retries=5) +subtensor.reveal_weights(wallet, netuid, uids, weights, salt, max_retries=5) +subtensor.set_weights(wallet, netuid, uids, weights, max_retries=5) + +# ✅ New: +subtensor.commit_weights(wallet, netuid, uids, weights, max_attempts=5) +subtensor.reveal_weights(wallet, netuid, uids, weights, salt, max_attempts=5) +subtensor.set_weights(wallet, netuid, uids, weights, max_attempts=5) +``` + +**New Validation:** The `max_attempts` parameter now includes validation. If `max_attempts=0` or negative, the method will return an `ExtrinsicResponse` with `success=False` and an appropriate error message instead of attempting the operation. + +## Breaking Changes:Removed Methods + +### Duplicate References + +```python +# ❌ Removed (was just a reference): +subtensor.get_stake_info_for_coldkey = subtensor.get_stake_for_coldkey + +# ✅ Use the canonical name: +subtensor.get_stake_info_for_coldkey(coldkey_ss58) +``` + +### DefaultConfig Class Removed + +```python +# ❌ Removed: +from bittensor.core.config import DefaultConfig + +# ✅ Use Config directly: +from bittensor.core.config import Config +``` + +The `DefaultConfig` class has been removed as it was unused in the codebase. + +### DelegateInfo Attribute Removed + +```python +# ❌ Removed: +delegate_info.total_daily_return # No longer calculated or provided + +# This attribute has been removed from both DelegateInfo and DelegateInfoLite classes +``` + +The `total_daily_return` attribute has been removed as it was not providing accurate information and should not be relied upon. + +## Extrinsic Calling Changes + +All functions that submit extrinsics to the Subtensor blockchain (both standalone functions and `Subtensor` class methods) have been standardized for consistency. + +### Standardized Parameters + +All functions that submit extrinsics now follow a **consistent parameter ordering** and include standard flags: + +```python +# Standard parameter order: +extrinsic_function( + subtensor, + # ... extrinsic-specific parameters (wallet, netuid, hotkey_ss58, amount, etc.) ... + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, +) +``` + +1. **Extrinsic-specific arguments come first** (e.g., `wallet`, `hotkey_ss58`, `netuid`, `amount`) +2. **Optional general flags come last** (e.g., `period`, `raise_error`, `wait_for_inclusion`, `wait_for_finalization`) +3. **Default behavior changed**: `wait_for_inclusion` and `wait_for_finalization` now default to `True` + +This ensures the SDK function response correctly reflects the blockchain transaction outcome. + +:::note +When `raise_error=False`, extrinsic functions do not raise exceptions; all error information is captured inside the returned `ExtrinsicResponse` object. Set `raise_error=True` if you prefer exceptions to be raised directly for error cases. +::: + +### ExtrinsicResponse Return Type + +All SDK functions that submit extrinsics to the blockchain now return an `ExtrinsicResponse` object instead of `bool` or tuples. + +- **`success`**: Primary indicator - `True` if transaction succeeded, `False` otherwise +- **`message`**: User-friendly status (e.g., "Success", "Insufficient balance") +- **`extrinsic_fee`**: Network fee paid to validators (similar to gas fees) - see [Transaction Fees](../learn/fees) +- **`transaction_tao_fee`**: Application-level fee charged in TAO for swap-based staking operations (0.05% of transacted liquidity when applicable) +- **`transaction_alpha_fee`**: Application-level fee charged in Alpha (subnet token) for swap-based staking operations (0.05% of transacted liquidity when applicable) +- **`extrinsic_receipt`**: Contains block number, hash, events, and execution details when `wait_for_inclusion=True` +- **`data`**: Operation-specific results: + - Registration: `{"uid": int}` - assigned neuron UID + - Commit weights: `{"reveal_round": int}` - round for revealing + - Metadata: `{"encrypted": bytes, "reveal_round": int}` + - Stake operations: balance information +- **`error`**: Python exception for programmatic error handling when `raise_error=False` + +See [source code](https://github.com/opentensor/bittensor/blob/main/bittensor/core/types.py#L290-L484). + +### Parameter Renames + +Many parameters in functions that submit blockchain transactions have been renamed for consistency across the SDK: + +#### Hotkey and Coldkey Parameters + +**All SS58 address parameters now use the `_ss58` suffix:** + +```python +# ❌ Old: +subtensor.move_stake(wallet, origin_hotkey, destination_hotkey, amount) + +# ✅ New: +subtensor.move_stake(wallet, origin_netuid, origin_hotkey_ss58, destination_netuid, destination_hotkey_ss58, amount) +``` + +**Affected methods:** + +- `hotkey` → `hotkey_ss58` (all methods) +- `hotkey_ss58_address` → `hotkey_ss58` (all methods) +- `coldkey` → `coldkey_ss58` (all methods) +- `coldkey_ss58_address` → `coldkey_ss58` (all methods) +- `hotkeypub` → `hotkeypub_ss58` (where applicable) +- `coldkeypub` → `coldkeypub_ss58` (where applicable) + +#### Transfer Extrinsic + +```python +# ❌ Old: +subtensor.transfer(wallet, dest, amount) + +# ✅ New: +subtensor.transfer(wallet, destination_ss58, amount) +``` + +#### Staking Parameters + +```python +# ❌ Old: +subtensor.unstake(wallet, hotkey, amount, safe_staking=True) +subtensor.swap_stake(wallet, from_hotkey, to_hotkey, amount, safe_staking=True) + +# ✅ New: +subtensor.unstake(wallet, netuid, hotkey_ss58, amount, safe_unstaking=True) + +# For swapping stake between subnets (same hotkey, different subnets): +subtensor.swap_stake( + wallet, + hotkey_ss58="5D...", + origin_netuid=1, + destination_netuid=2, + amount=amount, + safe_swapping=True +) + +# For moving stake between hotkeys (use move_stake instead): +subtensor.move_stake( + wallet, + origin_netuid=1, + origin_hotkey_ss58="5D...1", + destination_netuid=1, + destination_hotkey_ss58="5D...2", + amount=amount +) +``` + +#### Required Parameters + +Several previously optional parameters are now **required**: + +```python +# ❌ Old: +subtensor.add_stake(wallet, hotkey_ss58=None, amount=None) + +# ✅ New: +subtensor.add_stake( + wallet, + netuid: int, # Now required + hotkey_ss58: str, # Now required + amount: Balance # Now required +) +``` + +**Affected functions:** + +- `add_stake_extrinsic`: `netuid`, `hotkey_ss58`, `amount` now required +- `add_stake_multiple_extrinsic`: `amounts` now required +- `unstake_extrinsic`: `netuid`, `hotkey_ss58`, `amount` now required +- `unstake_multiple_extrinsic`: `amounts` now required + +### Removed Functions + +#### `unstake_all` parameter removed from `unstake_extrinsic` + +```python +# ❌ Old: +subtensor.unstake(wallet, hotkey, amount=None, unstake_all=True) + +# ✅ New: Use dedicated method +subtensor.unstake_all(wallet, netuid, hotkey_ss58) +``` + +#### Internal `_do*` methods removed + +All internal helper methods have been consolidated into the main functions that submit extrinsics: + +- `_do_commit_reveal_v3` → merged into `commit_timelocked_weights_extrinsic` +- `_do_commit_weights` → merged into `commit_weights_extrinsic` +- `_do_reveal_weights` → merged into `reveal_weights_extrinsic` +- `_do_set_weights` → merged into `set_weights_extrinsic` +- `_do_burned_register` → merged into `burned_register_extrinsic` +- `_do_pow_register` → merged into `register_extrinsic` +- `_do_set_root_weights` → merged into `set_root_weights_extrinsic` +- `_do_transfer` → merged into `transfer_extrinsic` + +#### Deprecated root weights method removed + +```python +# ❌ Removed: +subtensor.set_root_weights_extrinsic(...) + +# This was obsolete and has been removed entirely +``` + +#### Commit-Reveal v3 (CRv3) removed + +All CRv3-related logic and extrinsics have been removed as CRv3 is no longer supported on the chain. + +```python +# ❌ Removed: +commit_reveal_extrinsic(...) # Old non-mechanism version + +# ✅ Use: +commit_timelocked_weights_extrinsic(..., commit_reveal_version=4) +``` + +### Merged Functions + +#### `increase_take` and `decrease_take` merged into `set_delegate_take` + +```python +# ❌ Old: +subtensor.increase_take(wallet, hotkey_ss58, take) +subtensor.decrease_take(wallet, hotkey_ss58, take) + +# ✅ New: +# Automatically determines whether to increase or decrease based on current vs new take +subtensor.set_delegate_take( + wallet, + hotkey_ss58="5D...", + take=0.18 # 18% as a float between 0 and 1 +) + +# ✅ New (low-level extrinsic with explicit action): +# The extrinsic requires an explicit action parameter with a strict type: +# action: Literal["increase_take", "decrease_take"] +from bittensor.core.extrinsics.take import set_take_extrinsic + +# Example: increase take +response_inc = set_take_extrinsic( + subtensor, + wallet=wallet, + hotkey_ss58="5D...", + take=0.20, + action="increase_take", +) + +# Example: decrease take +response_dec = set_take_extrinsic( + subtensor, + wallet=wallet, + hotkey_ss58="5D...", + take=0.15, + action="decrease_take", +) +``` + +**Note:** The method automatically calls `increase_take` or `decrease_take` internally based on whether the new take is higher or lower than the current take. + +#### Mechanism-specific weight functions consolidated + +Non-mechanism versions removed, mechanism versions renamed and moved: + +```python +# Old paths (removed): +from bittensor.core.extrinsics.mechanism import ( + commit_timelocked_mechanism_weights_extrinsic, + commit_mechanism_weights_extrinsic, + reveal_mechanism_weights_extrinsic, +) + +# ✅ New paths: +from bittensor.core.extrinsics.weights import ( + commit_timelocked_weights_extrinsic, + commit_weights_extrinsic, + reveal_weights_extrinsic, + set_weights_extrinsic, +) +``` + +## Balance Handling + +### Stricter Type Checking + +**Balance operations now raise errors instead of warnings** for type mismatches. + +#### 1) Invalid balance type (`BalanceTypeError`) + +Raised when a method expecting a `Balance` receives a non-`Balance` value. + +```python +from bittensor.utils.balance import Balance, tao, rao +from bittensor.core.errors import BalanceTypeError + +# ❌ Old (pre-10.0): would warn but continue +amount = 1.0 # float +# subtensor.transfer(wallet, dest, amount) + +# ✅ New: must pass a Balance object (choose your preferred constructor) +subtensor.transfer(wallet, dest, tao(1.0)) +subtensor.transfer(wallet, dest, rao(1_000_000_000)) +subtensor.transfer(wallet, dest, Balance.from_tao(1.0)) +subtensor.transfer(wallet, dest, Balance.from_rao(1_000_000_000)) +``` + +#### 2) Mismatched balance units (`BalanceUnitMismatchError`) + +Raised when performing operations on two `Balance` objects that represent different units (e.g., TAO vs Alpha from a subnet). + +```python +from bittensor.utils.balance import Balance +from bittensor.core.errors import BalanceUnitMismatchError + +balance_tao = Balance.from_tao(1.0) +balance_alpha = Balance.from_rao(1_000_000_000) # 1 tao = 1x10^9 rao + +# ❌ Will raise BalanceUnitMismatchError: mixing units in arithmetic +_ = balance_tao + balance_alpha + +# ❌ Will raise BalanceUnitMismatchError: comparing mismatched units +_ = balance_tao > balance_alpha + +# ✅ Ensure units match before operations +_ = balance_tao + Balance.from_tao(0.5) +``` + +### Function Renames + +```python +# ❌ Old: +from bittensor.utils.balance import check_balance, check_and_convert_to_balance + +amount = check_and_convert_to_balance(value) + +# ✅ New: +from bittensor.utils.balance import check_balance_amount + +amount = check_balance_amount(value) +``` + +### All Amount Parameters Require Balance Objects + +```python +# ❌ Old: +subtensor.transfer(wallet, destination, 1.0) # float accepted +subtensor.add_stake(wallet, hotkey, 5) # int accepted + +# ✅ New: +from bittensor.utils.balance import tao, rao + +subtensor.transfer(wallet, destination, tao(1.0)) # convenience helper +subtensor.add_stake(wallet, netuid, hotkey_ss58, tao(5.0)) +# or +subtensor.transfer(wallet, destination, rao(1000000000)) +``` + +**Affected methods:** + +- `transfer` +- `add_stake` +- `add_stake_multiple` +- `unstake` +- `unstake_multiple` +- `move_stake` +- `swap_stake` +- `transfer_stake` +- `get_transfer_fee` +- `get_stake_add_fee` +- `get_stake_movement_fee` +- `get_unstake_fee` + +## Import Changes + +### Removed Backwards Compatibility Aliases + +The following lowercase aliases have been **removed** from `bittensor`: + +```python +# ❌ Old (removed): +from bittensor import subtensor, wallet, config, axon, dendrite +from bittensor import keyfile, metagraph, synapse, async_subtensor + +# ✅ New (use PascalCase): +from bittensor import Subtensor, Wallet, Config, Axon, Dendrite +from bittensor import Keyfile, Metagraph, Synapse, AsyncSubtensor +``` + +### Removed Direct Subpackage Links + +```python +# ❌ Old (removed): +from bittensor.mock import MockSubtensor +from bittensor.extrinsics import transfer_extrinsic + +# ✅ New (use top-level convenience imports or full paths): +from bittensor import mock, extrinsics +mock_sub = mock.MockSubtensor() +response = extrinsics.transfer.transfer_extrinsic(...) + +# Or use full paths: +from bittensor.utils.mock import MockSubtensor +from bittensor.core.extrinsics import transfer_extrinsic +``` + +### New Import Convenience + +```python +# ✅ New convenience imports: +from bittensor import extrinsics +from bittensor import mock +from bittensor import get_async_subtensor + +# Use them: +response = extrinsics.transfer.transfer_extrinsic(...) +mock_sub = mock.MockSubtensor() +async_sub = get_async_subtensor(network="test") +``` + +### Module Reorganization + +Several modules have been moved to new subpackages: + +```python +# ❌ Old: +from bittensor.core.subtensor_api import SubtensorAPI +from bittensor.core.timelock import TimelockManager + +# ✅ New: +from bittensor.extras.subtensor_api import SubtensorAPI +from bittensor.extras import timelock + +# Or use top-level convenience import: +from bittensor import SubtensorApi, timelock +``` + +The `bittensor.extras` package now hosts optional extensions like `SubtensorApi`, `timelock` and `dev_framework`. + +### Extrinsic Parameters Package + +Parameters for functions that submit extrinsics are now centralized in a dedicated package, `bittensor.core.extrinsics.params`. + +This makes it easier to discover available parameters and ensures consistency across sync/async implementations of blockchain transaction functions. + +## Environment Variables + +### Renamed Variables + +```python +# ❌ Old: +BT_CHAIN_ENDPOINT=ws://127.0.0.1:9945 +BT_NETWORK=local + +# ✅ New: +BT_SUBTENSOR_CHAIN_ENDPOINT=ws://127.0.0.1:9945 +BT_SUBTENSOR_NETWORK=local +``` + +**All renamed environment variables:** + +- `BT_CHAIN_ENDPOINT` → `BT_SUBTENSOR_CHAIN_ENDPOINT` +- `BT_NETWORK` → `BT_SUBTENSOR_NETWORK` + +### Disabling CLI Argument Parsing + +If your script uses the SDK and receives unwanted `--config` or other CLI parameters: + +```python +# Set environment variable to disable config processing: +BT_NO_PARSE_CLI_ARGS=1 # or: true, yes, on + +# In code: +import os +os.environ['BT_NO_PARSE_CLI_ARGS'] = '1' + +from bittensor import Subtensor +# CLI args will no longer be processed +``` + +:::tip +When `BT_NO_PARSE_CLI_ARGS` is set, the SDK skips CLI parsing entirely and falls back to default configuration values defined in `bittensor.core.settings.DEFAULTS` for all configuration options across the SDK. This is useful when embedding the SDK in applications that manage their own configuration. +::: + +## Metagraph Changes + +This section covers changes to metagraph-related functionality in both the `Subtensor` and `Metagraph` classes, particularly around the new multiple incentive mechanisms feature. + +### Mechid Parameter Ordering + +With the introduction of multiple incentive mechanisms per subnet, many methods now accept a `mechid` (mechanism ID) parameter to specify which mechanism to query: + +```python +# Query methods with mechid support (parameter order: netuid, mechid=0, block=None) +bonds = subtensor.bonds(netuid=1, mechid=0) +weights = subtensor.weights(netuid=1, mechid=0) +metagraph = subtensor.metagraph(netuid=1, mechid=0) +commits = subtensor.get_timelocked_weight_commits(netuid=1, mechid=0) +``` + +**Methods with mechid parameter:** + +- `bonds(netuid, mechid=0, block=None)` +- `weights(netuid, mechid=0, block=None)` +- `metagraph(netuid, mechid=0, lite=True, block=None)` +- `get_metagraph_info(netuid, mechid=0, ...)` +- `get_timelocked_weight_commits(netuid, mechid=0, block=None)` +- `commit_weights(wallet, netuid, uids, weights, mechid=0, ...)` +- `reveal_weights(wallet, netuid, uids, weights, mechid=0, ...)` +- `set_weights(wallet, netuid, uids, weights, mechid=0, ...)` + +### MetagraphInfo Changes + +The `MetagraphInfo` class now requires a `mechid` parameter to support multiple incentive mechanisms: + +```python +# mechid is now required in MetagraphInfo +from bittensor.core.chain_data.metagraph_info import MetagraphInfo + +info = MetagraphInfo( + netuid=1, + mechid=0, # Now required (mechanism ID) + # ... other fields +) +``` + +**Note:** `mechid=0` refers to the first (or only) incentive mechanism in a subnet. Subnets can have multiple mechanisms (currently limited to 2), each with their own independent weight matrices and emissions. See [Multiple Incentive Mechanisms](../subnets/understanding-multiple-mech-subnets) for details. + +### Async Metagraph Initialization + +The async `AsyncMetagraph.sync` method no longer terminates the subtensor instance after use, improving resource management and allowing for reuse of connections in async contexts. + +## Migration Checklist + +1. **Update Python version** to 3.10 or higher +2. **Update bittensor package**: `pip install bittensor>=10.0.0` (until the public release, you should install the latest available release candidate). +3. **Update all imports** to use PascalCase class names (`Subtensor`, `Wallet`, etc.), also known as the CapWords convention. +4. **Replace all amount parameters** with `Balance` objects.` +5. **Update all functions that submit extrinsics** to handle `ExtrinsicResponse` return type instead of `bool` or tuples[bool, str] +6. **Rename parameters** according to the standardization (`hotkey` → `hotkey_ss58`, `dest` → `destination`, etc.) +7. **Update environment variables** (`BT_CHAIN_ENDPOINT` → `BT_SUBTENSOR_CHAIN_ENDPOINT`, `BT_NETWORK` → `BT_SUBTENSOR_NETWORK`) +8. **Review removed methods** and replace with alternatives (see [Removed Methods](#removed-methods)) +9. **Update parameter order** for affected methods (see [Parameter Changes](#parameter-changes)) +10. **Add `mechid` parameter** to weight-setting code if working with multiple mechanisms +11. **Test thoroughly** with your specific use case, especially blockchain transactions and balance handling diff --git a/docs/sdk/subtensor-api.md b/docs/sdk/subtensor-api.md index d81eea69b3..64be1be0aa 100644 --- a/docs/sdk/subtensor-api.md +++ b/docs/sdk/subtensor-api.md @@ -74,6 +74,36 @@ print(sub.delegates.get_delegate_identities()) sub.chain.tx_rate_limit() ``` +### Mechanism helpers (multiple incentive mechanisms) + +Subnets can run multiple incentive mechanisms. The API adds helpers and optional `mechid` on key calls. + +- New getters: + - `get_mechanism_count(netuid)` → int + - `get_mechanism_emission_split(netuid)` → list[int] or None (even split implied) + - `is_in_admin_freeze_window(netuid)` → bool +- Mechanism-aware methods now accept `mechid` (default `0`): + - `set_weights`, `commit_weights`, `reveal_weights`, `weights`, `bonds`, `get_metagraph_info`, `get_all_metagraphs_info(all_mechanisms=False)` + +```python +import bittensor as bt + +sub = bt.SubtensorApi() +netuid = 14 + +count = sub.get_mechanism_count(netuid=netuid) +split = sub.get_mechanism_emission_split(netuid=netuid) + +# Set weights for mechanism 1 +ok, msg = sub.set_weights( + wallet=bt.Wallet("alice"), + netuid=netuid, + mechid=1, + uids=[0,1,2], + weights=[1,1,1], +) +``` + ### Asynchronous ```python diff --git a/docs/staking-and-delegation/delegation.md b/docs/staking-and-delegation/delegation.md index b6c0b8c846..409d65821c 100644 --- a/docs/staking-and-delegation/delegation.md +++ b/docs/staking-and-delegation/delegation.md @@ -9,105 +9,116 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; TAO holders can **stake** any amount of the liquidity they hold to a validator. Also known as **delegation**, staking supports validators, because their total stake in the subnet, including stake delegated to them by others, determines their consensus power and their share of emissions. After the validator/delegate extracts their **take** the remaining emissions are credited back to the stakers/delegators in proportion to their stake with that validator. +:::note Transaction Fees +Staking and unstaking operations incur transaction fees. See [Transaction Fees in Bittensor](../learn/fees.md) for details. +::: + See also: + - [Staking with Polkadot JS](./staking-polkadot-js.md). - See also [Validators: Acquiring stake](../validators/index.md#acquiring-stake). - :::tip tips -Validators/delegates can configure their take. The default value is 18%. See [Setting your delegate take](#setting-your-delegate-take). +Validators/delegates can configure their take. The default value is 18%. See [`btcli sudo set-take`](../btcli#btcli-sudo-set-take). Minimum required stake for nominators is 0.1 TAO. ::: Staking is always local to a subnet. -Each subnet operates its own automated market-maker (AMM), meaning it mantains its own reserves of the two tokens being traded so that it can facilitate a trade of any desired quantity of liquidity (as long as its available), at a price that it automated calculates. +Each subnet operates its own automated market maker (AMM), meaning it mantains its own reserves of the two tokens being traded so that it can facilitate a trade of any desired quantity of liquidity (as long as its available), at a price that it automated calculates. Each subnet has a reserve of TAO and a reserve of its currency, referred to in general as its alpha ($\alpha$) currency. Stake is held in $\alpha$ token denominations. -As a TAO holder you will stake to a validator’s hotkey on a specific subnet. Staking to a given validator's hotkeys on different subnets is independent. +As a TAO holder, you will stake to a validator’s hotkey on a specific subnet. Staking to a given validator's hotkeys on different subnets is independent. **When you stake:** -1. First, your TAO stake goes into the subnet's TAO reserve of its AMM (automated market maker) pool. -1. Then, the subnet AMM pool algorithm uses the exchange rate and calculates the equivalent units of $\alpha$, for the TAO that was just added to the TAO reserve side. This amount of $\alpha$ is taken out of the alpha reserve of the pool and is sent to the validator’s hotkey. -1. The validator’s hotkey holds the $\alpha$. The sum of stake among all hotkeys is referred as **$\alpha$ outstanding** for that subnet. +1. First, your TAO stake goes into the subnet's TAO reserve of its AMM pool. +1. Then, the subnet's AMM pool algorithm uses the latest exchange rate and calculates the equivalent units of $\alpha$, for the TAO that was just added to the TAO reserve side. This amount of $\alpha$ is taken out of the alpha reserve of the pool and is sent to the validator’s hotkey. +1. The validator’s hotkey holds the $\alpha$. The sum of stake among all hotkeys is referred as **$\alpha$ outstanding** for that subnet. **When you unstake:** -1. When you issue an unstake command, `btcli stake remove`, and specify the units of $\alpha$ token you want to unstake, this $\alpha$ is first taken out of the validator’s hotkey and added to the $\alpha$ reserves of the subnet pool. -2. The subnet AMM pool algorithm then applies the latest exchange rate and calculates the equivalent TAO units for the $\alpha$ token units that were just added to the $\alpha$ reserves of the pool. +1. When you issue an unstake command, `btcli stake remove`, and specify the units of $\alpha$ token you want to unstake, this $\alpha$ is first taken out of the validator’s hotkey and added to the $\alpha$ reserves of the subnet pool. +2. The subnet's AMM pool algorithm then applies the latest exchange rate and calculates the equivalent TAO units for the $\alpha$ token units that were just added to the $\alpha$ reserves of the pool. 3. These equivalent TAO units are then taken out of the TAO reserves of the subnet pool and are sent to the TAO holder’s coldkey. :::tip Stake is always expressed in alpha units -In Dynamic TAO, except for the stake held in [the Root Subnet](#root-subnet-subnet-zero), the stake held by a hotkey in a subnet is always expressed in the subnet-specific $\alpha$ units. Root Subnet stake is expressed in $\tau$. +In Dynamic TAO, except for the stake held in [the Root Subnet](../subnets/understanding-subnets.md#subnet-zero), the stake held by a hotkey in a subnet is always expressed in the subnet-specific $\alpha$ units. Root Subnet stake is expressed in $\tau$. ::: :::tip Prereq To follow along, install the [latest release of `btcli`](https://pypi.org/project/bittensor-cli/). ::: +
+ See how its calculated ## Example Suppose a validator holds 800 TAO of their own. -Then three nominators stake to the validator as follows: - - Nominator 1: 100 TAO. - - Nominator 2: 70 TAO. - - Nominator 3: 30 TAO. +Then three nominators stake to the validator as follows: + +- Nominator 1: 100 TAO. +- Nominator 2: 70 TAO. +- Nominator 3: 30 TAO. The validator's effective stake is the total sum of their own and all delegated stake. - $$ - \text{delegated stake} = 100\tau + 70\tau + 30\tau = 200\tau - $$ - $$ - \text{total stake} = \text{self-stake} + \text{delegated stake} = 800\tau + 200\tau = 1000 \tau - $$ +$$ +\text{delegated stake} = 100\tau + 70\tau + 30\tau = 200\tau +$$ + +$$ +\text{total stake} = \text{self-stake} + \text{delegated stake} = 800\tau + 200\tau = 1000 \tau +$$ Emissions to stakers are proportional to their contribution to delegated stake: $$ - \text{emission for staker x from validator V} = + \text{emission for staker x from validator V} = \frac { stake_x } { \sum_{i \in \text{V's stakers}} \bigl(stake_i) } $$ + - Nominator 1 represents 50% of total delegated TAO: - $$ - \text{emission for staker x from validator V} = - \frac - { 100\tau } - { 100\tau + 70\tau + 30\tau } = 50\% - $$ + $$ + \text{emission for staker x from validator V} = + \frac + { 100\tau } + { 100\tau + 70\tau + 30\tau } = 50\% + $$ + - Nominator 2 contributes 35% of the total delegated TAO. - $$ - \text{emission for staker x from validator V} = + $$ + \text{emission for staker x from validator V} = \frac { 70\tau } { 100\tau + 70\tau + 30\tau } = 35\% - $$ + $$ - Nominator 3 contributes 15% of the total delegated TAO. - $$ - \text{emission for staker x from validator V} = + $$ + \text{emission for staker x from validator V} = \frac { 30\tau } { 100\tau + 70\tau + 30\tau } = 15\% - $$ + $$ The delegate validator would keep 80% of the emissions, based on their 80% proportion of the total stake (0.8). In addition, the validator would keep their 18% take of the emissions earned on the delegated stake. As a result: - - Total emissions to the delegate are: $0.8 + 0.2*0.18= .836 = 83.6\%$ of the received emissions. - - Each nominator receives the following portions of the validator's total emissions, based on their contribution percentages: - - Nominator 1 emissions: $(1-0.8)*(1-0.18)*.5 = .082 = 8.2\%$ - - Nominator 2 emissions: $(1-0.8)*(1-0.18)*.35 = .0574 = 5.74\%$ - - Nominator 3 emissions: $(1-0.8)*(1-0.18)*.15 = .0246 = 2.46\%$ - + +- Total emissions to the delegate are: $0.8 + 0.2*0.18= .836 = 83.6\%$ of the received emissions. +- Each nominator receives the following portions of the validator's total emissions, based on their contribution percentages: + - Nominator 1 emissions: $(1-0.8)*(1-0.18)*.5 = .082 = 8.2\%$ + - Nominator 2 emissions: $(1-0.8)*(1-0.18)*.35 = .0574 = 5.74\%$ + - Nominator 3 emissions: $(1-0.8)*(1-0.18)*.15 = .0246 = 2.46\%$ :::info A nominator is a delegating authority A nominator is the same as a delegating authority. Typically, a nominator is an owner of TAO funds who wants to invest in the Bittensor network without performing any validating tasks. ::: +
diff --git a/docs/staking-and-delegation/managing-stake-btcli.md b/docs/staking-and-delegation/managing-stake-btcli.md index 8f093a7a14..8b243ca5bb 100644 --- a/docs/staking-and-delegation/managing-stake-btcli.md +++ b/docs/staking-and-delegation/managing-stake-btcli.md @@ -8,10 +8,14 @@ This pages demonstrates usage of `btcli`, the Bittensor CLI, for managing stake. TAO holders can **stake** any amount of the liquidity they hold to a validator. Also known as **delegation**, staking supports validators, because their total stake in the subnet, including stake delegated to them by others, determines their consensus power and their share of emissions. After the validator/delegate extracts their **take** the remaining emissions are credited back to the stakers/delegators in proportion to their stake with that validator. +:::note Transaction Fees +Staking and unstaking operations incur transaction fees for the underlying blockchain transactions they trigger. See [Transaction Fees in Bittensor](../learn/fees.md) for details. +::: + See also: - [Staking/delegation overview](./delegation) -- [Understanding pricing and anticipating slippage](../dynamic-tao/staking-unstaking-dtao) +- [Understanding pricing and anticipating slippage](../learn/slippage) :::tip Minimum transaction amount for stake/unstake/move/transfer: 500,000 RAO or 0.0005 TAO. @@ -33,7 +37,7 @@ Test network tokens have no real value. Before managing liquidity on Bittensor m ## View TAO balance -To stake, you'll first need some TAO. Inquire in [Discord](https://discord.com/channels/799672011265015819/1107738550373454028/threads/1331693251589312553) to obtain TAO on Bittensor test network. Alternatively, you can transfer some testnet TAO to your wallet address using the [BTCLI Live Coding Playground](../btcli/btcli-playground.md#transfer). +To stake, you'll first need some TAO. Inquire in [Discord](https://discord.com/channels/799672011265015819/1107738550373454028/threads/1331693251589312553) to obtain TAO on Bittensor test network. Alternatively, you can obtain some by completing the [BTCLI Live Coding Playground](../btcli/btcli-playground.md#transfer). After creating a wallet, ensure that you are targeting the test network by running the `btcli config set` command. Next, select network, and set it to `test`. @@ -164,7 +168,7 @@ After selecting a validator to delegate stake to, you'll see your wallet balance Amount to stake (TAO τ): 5 ``` -You'll then see the details of the trade, including [slippage](../dynamic-tao/staking-unstaking-dtao), and be asked to confirm execution. +You'll then see the details of the trade, including [slippage](../learn/slippage), and be asked to confirm execution. ```console Staking to: @@ -190,7 +194,21 @@ The columns are as follows: Would you like to continue? [y/n]: ``` -If you confirm, the staking operation will execute. After completion +If you confirm, the staking operation will execute. + +### Staking into multiple nodes + +You can also stake into multiple nodes by running the following command in your terminal: + +```shell +btcli stake add -n 4,14,70 +``` + +The command accepts a comma-separated list of the subnets you wish to stake into. If you want to stake the same amount of TAO into all subnets, you can include the `--amount` flag as shown: + +```shell +btcli stake add -n 4,14,70 --amount 100 +``` ## View your current stakes diff --git a/docs/staking-and-delegation/managing-stake-sdk.md b/docs/staking-and-delegation/managing-stake-sdk.md index 6bc7e6cbb7..9ed20a1720 100644 --- a/docs/staking-and-delegation/managing-stake-sdk.md +++ b/docs/staking-and-delegation/managing-stake-sdk.md @@ -11,7 +11,7 @@ TAO holders can **stake** any amount of the liquidity they hold to a validator. See also: - [Staking/delegation overview](./delegation) -- [Understanding pricing and anticipating slippage](../dynamic-tao/staking-unstaking-dtao) +- [Understanding pricing and anticipating slippage](../learn/slippage) :::tip Minimum transaction amount for stake/unstake/move/transfer: 500,000 RAO or 0.0005 TAO. @@ -19,7 +19,7 @@ Minimum transaction amount for stake/unstake/move/transfer: 500,000 RAO or 0.000 ## Check your TAO balance -To stake, you'll first need some TAO. Inquire in [Discord](https://discord.com/channels/799672011265015819/1107738550373454028/threads/1331693251589312553) to obtain TAO on Bittensor test network. Alternatively, you can transfer some testnet TAO to your wallet address using the [BTCLI Live Coding Playground](../btcli/btcli-playground.md#transfer). +To stake, you'll first need some TAO. Inquire in [Discord](https://discord.com/channels/799672011265015819/1107738550373454028/threads/1331693251589312553) to obtain TAO on Bittensor test network. Alternatively, you can obtain some by completing the [BTCLI Live Coding Playground](../btcli/btcli-playground.md#transfer). :::danger The funds in a crypto wallet are only as secure as your private key and/or seed phrase, and the devices that have access to these. diff --git a/docs/staking-and-delegation/stakers-btcli-guide.md b/docs/staking-and-delegation/stakers-btcli-guide.md index 118a6508a0..a006cb4bf2 100644 --- a/docs/staking-and-delegation/stakers-btcli-guide.md +++ b/docs/staking-and-delegation/stakers-btcli-guide.md @@ -6,53 +6,61 @@ title: "Staker's Guide to `BTCLI`" This page prepares the reader for managing TAO and alpha stake using `btcli` in a secure manner. -For general coverage of `btcli` security and usage considerations across persona, see: [Bittensor CLI: Permissions Guide](../btcli-permissions) +:::note Transaction Fees +Staking and unstaking operations incur transaction fees. See [Transaction Fees in Bittensor](../learn/fees.md) for details. +::: + +For general coverage of `btcli` security and usage considerations across persona, see: [Bittensor CLI: Permissions Guide](../btcli/btcli-permissions) ## Intro -Stakers enter value into the Bittensor network by acquiring TAO and staking or *delegating* it to validators to support their work. As validators extract emissions, a certain percentage goes back to stakers. +Stakers enter value into the Bittensor network by acquiring TAO and staking or _delegating_ it to validators to support their work. As validators extract emissions, a certain percentage goes back to stakers. Stakers must be familiar with operations related to managing the TAO and staked alpha tokens in their Bittensor wallet balances. -Account balances are public information, and can be viewed *without* using a coldkey, even in an insecure environment. However, any account operation that **changes the state** of the Bittensor chain, such as a balance transfer or staking operation, must be signed with your wallet's coldkey private key. +Account balances are public information, and can be viewed _without_ using a coldkey, even in an insecure environment. However, any account operation that **changes the state** of the Bittensor chain, such as a balance transfer or staking operation, must be signed with your wallet's coldkey private key. -Performing these functions requires using a **coldkey**, and hence must be performed in a [**highly secure environment**](../getting-started/coldkey-hotkey-security) for any wallet connected to real (mainnet) TAO balance. A leak of your coldkey can lead to a catastrophic loss of funds. +Performing these functions requires using a **coldkey**, and hence must be performed in a [**highly secure environment**](../keys/coldkey-hotkey-security) for any wallet connected to real (mainnet) TAO balance. A leak of your coldkey can lead to a catastrophic loss of funds. -Any operation can be practiced against Bittensor testnet using throw-away keys *not* connected to your real TAO balances on mainnet. +Any operation can be practiced against Bittensor testnet using throw-away keys _not_ connected to your real TAO balances on mainnet. :::tip Stakers only need a coldkey. Unless you plan to mine, validate, or participate in governance, you do not need a hotkey. ::: See: + - [Staking/Delegation Overview](./delegation.md) -- [Bittensor CLI: Permissions Guide](../btcli-permissions) -- [Wallets, Coldkeys and Hotkeys in Bittensor](../getting-started/wallets) -- [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security) +- [Bittensor CLI: Permissions Guide](../btcli/btcli-permissions) +- [Wallets, Coldkeys and Hotkeys in Bittensor](../keys/wallets) +- [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security) ## Requirements for wallet, balance and staking functions ### Wallets - - View balances and stake—only coldkey public key is required (permissionless) - - Create or generate a new coldkey. - - Transfer TAO from your coldkey to another address. Requires a coldkey signature (secure environment). + +- View balances and stake—only coldkey public key is required (permissionless) +- Create or generate a new coldkey. +- Transfer TAO from your coldkey to another address. Requires a coldkey signature (secure environment). ### Subnet Discovery - - `btcli subnets list`, `btcli subnets show`, `btcli subnets metagraph`: See available subnets or node info. Permissionless read. - - `btcli subnets price`, `btcli subnets burn-cost`, `btcli subnets burn_cost`: Show the required burn to register in a particular subnet. Permissionless read. + +- `btcli subnets list`, `btcli subnets show`, `btcli subnets metagraph`: See available subnets or node info. Permissionless read. +- `btcli subnets price`, `btcli subnets burn-cost`, `btcli subnets burn_cost`: Show the required burn to register in a particular subnet. Permissionless read. ### Staking (All require **coldkey** except for list): - - Add, remove, or move stake to validators on specific subnets. - - Transfer ownership of stake to anoth - - `btcli stake child ...` / `btcli stake children ...` (get, set, revoke, take) - - Short aliases: `btcli st add`, `btcli st remove`, etc. + +- Add, remove, or move stake to validators on specific subnets. +- Transfer ownership of stake to anoth +- `btcli stake child ...` / `btcli stake children ...` (get, set, revoke, take) +- Short aliases: `btcli st add`, `btcli st remove`, etc. ### Workstation configuration - - `btcli config set`, `btcli config get`, etc. (Permissionless) to configure a `btcli` environment. + +- `btcli config set`, `btcli config get`, etc. (Permissionless) to configure a `btcli` environment. ## Key rotation If you suspect your coldkey may have been leaked, you can request to swap it out of your wallet, using an extrinsic blockchain transaction. This operation has a 5 day waiting period, during which your coldkey will be locked. The cost of this coldkey swap transaction is 0.1 TAO. -See [Rotate/Swap your Coldkey](../subnets/schedule-coldkey-swap) - +See [Rotate/Swap your Coldkey](../keys/schedule-coldkey-swap) diff --git a/docs/subnets/_legacy_hyperparams.md b/docs/subnets/_legacy_hyperparams.md index de302b54fb..9dfc514d2e 100644 --- a/docs/subnets/_legacy_hyperparams.md +++ b/docs/subnets/_legacy_hyperparams.md @@ -105,7 +105,7 @@ Consider Subnet-1 where `max_weight_limit` is set to 455 and `min_allowed_weight : The interval, measured as a number of blocks, that elapses before unencrypted weights are revealed. **Value** -: The commit reveal interval, as an integer count of blocks. +: The Commit Reveal interval, as an integer count of blocks. **Setting** : This parameter can be changed by the subnet owner, and must be tuned carefully for the subnet. It should always be greater than the [immunity period](#immunity_period) to avoid unintended miner deregistration—see [Commit Reveal and Immunity Period](./commit-reveal.md#commit-reveal-and-immunity-period). @@ -131,7 +131,7 @@ Varies between subnets, for example 7200 blocks for Subnet-1. **Setting** : This parameter can be changed by the subnet owner, and must be tuned carefully for the subnet. -If [Commit Reveal](./commit-reveal.md) is enabled for the subnet, the value of the commit reveal interval should always be greater than the immunity period within the subnet, to avoid unintended miner deregistration—see [Commit Reveal and Immunity Period](./commit-reveal.md#commit-reveal-and-immunity-period). +If [Commit Reveal](./commit-reveal.md) is enabled for the subnet, the value of the Commit Reveal interval should always be greater than the immunity period within the subnet, to avoid unintended miner deregistration—see [Commit Reveal and Immunity Period](./commit-reveal.md#commit-reveal-and-immunity-period). :::tip immunity period for a subnet diff --git a/docs/subnets/child-hotkeys.md b/docs/subnets/child-hotkeys.md deleted file mode 100644 index 9f2bf7d4bb..0000000000 --- a/docs/subnets/child-hotkeys.md +++ /dev/null @@ -1,278 +0,0 @@ ---- -title: "Child Hotkeys" ---- - -import ThemedImage from '@theme/ThemedImage'; -import useBaseUrl from '@docusaurus/useBaseUrl'; - -# Child Hotkeys - -This guide describes the **child hotkeys** feature and how to use it. With the child hotkeys, a subnet validator is no longer required to use the same delegate hotkey for every subnet they validate in. The subnet validator can use a separate **child hotkey** per subnet. The subnet validator does this by re-delegating a portion of their stake from their delegate hotkey to this separate child hotkey on a subnet. The originating delegate hotkey is called the **parent hotkey**. - -The owner of this child hotkey would then validate in the subnet on behalf of the parent hotkey. The child hotkey would receive a percentage `take` from the resulting dividends. - - - -
- -
- -
- -See the above diagram. Without the child hotkeys, a subnet validator's delegate hotkey would have to sign all the validation operations in all the subnets. This exposes the delegate hotkey in all the subnets. An attacker can get hold of the delegate hotkey from any one subnet in order to take over the validation operations with this hotkey, thereby crippling this subnet validator in all their subnets across the entire Bittensor network. - -
- -
- - -See the above diagram. With the child hotkeys, if an attacker steals a child hotkey, then only those subnets are at risk where this child hotkey is used as the delegate hotkey. - -## Benefits of child hotkeys - -- **Security for parent hotkeys**: Re-delegating stake to multiple child hotkeys enhances the security of the parent hotkey. Each child hotkey can validate on a specific subnet using a different machine. The child hotkey would sign the validation operations on behalf of the parent hotkey: There is no need to use the parent hotkey on any of these subnets. As a consequence, the exposure of the parent hotkey can be minimized. The parent hotkey can even be moved to a secure location until it is needed, for example, to revoke a child hotkey. -- **Validators can easily scale up**: As Bittensor scales up towards hundreds of subnets, it is not practical for a single delegate to validate in every single subnet. With child hotkeys, a validator can easily make this feasible by re-delegating and offloading the validating operations to multiple child hotkeys. -- **Increased bandwidth for a subnet owner**: A validator can also re-delegate to a subnet owner's hotkey. The subnet owner would then do the validation work on the subnet, in exchange for a percentage `take` from the resulting dividends. A subnet owner can increase their access bandwidth into their own subnet in this way. -- A child hotkey and a parent hotkey need not be owned by the same entity. -- A validator can re-delegate to a hotkey of any other validator on any subnet. After re-delegation, the hotkey that is the source of the stake is called **parent hotkey** and the hotkey that receives this re-delegated stake is called **child hotkey**. - :::tip "Child hotkey" and "parent hotkey" are terms of convenience - The terms "child hotkey" and "parent hotkey" are only terms of convenience. There is nothing inherently different about a "child hotkey" that separates it from a "parent hotkey". Neither have any special attributes compared to a normal hotkey. - ::: - ---- - -## Features - -The child hotkey features are as follows: - -- A hotkey must be registered on a subnet before it can be used as a parent hotkey. The hotkey can be registered on any subnet. -- A parent hotkey can have multiple child hotkeys. Similarly, a child hotkey can have more than one parent hotkey. -- A child hotkey can exist as a registered hotkey in multiple netuids simultaneously. -- **IMPORTANT**: For a given `netuid`, say, `netuid 5`, a single parent hotkey can have at most five (`5`) child hotkeys. Moreover, the same parent hotkey on a different `netuid 11` can have another set of `5` child hotkeys. Alternately, on this `netuid 11` the same parent hotkey can also have the same (`5`) child hotkeys that are in the netuid `5`. -- While setting the child hotkeys, the proportion field can have proportions that add to less than `1.0`. The proportion that was not assigned to the child hotkeys will remain with the parent hotkey. However, a proportion cannot be zero. A `0` proportion value will result in an error. Furthermore, in a given subnet, the sum of all proportions must not exceed `1.0`. - -## Rate limits - -The following rate limits apply for child hotkeys: - -- A child hotkey's take rate can only be adjusted once per 30 days. -- One successful execution of `set_children` or `revoke_children` is allowed for every 720 blocks. - -## Minimum stake - -The minimum stake you can redelegate to a child hotkey is as follows: -- **Testnet**: 100 testnet TAO. -- **Mainnet**: 1000 TAO. - ---- - -## Installing - -This feature is available in Bittensor 7.4.0 and later versions. See [Install Bittensor](../getting-started/installation.md). - -## Child hotkey commands - -Use the `btcli` command options described below to work with child hotkeys. - -## Setting a child hotkey - -This command assigns a proportion of the parent hotkey's stake weight to the child hotkeys. Specific proportion for each child hotkey can be set. The parent hotkey must be registered on at least one `netuid`. This `netuid` need not be the same `netuid` used in this command. Only the stake TAO of the parent hotkey can be assigned to the child hotkeys. - -### Usage - -```bash -btcli stake set_children --netuid --children --proportions --hotkey --wallet.name -``` - -### Parameters - -- `--netuid:` Integer. Should be a single integer value representing a current subnet's `netuid`. - - Must be greater than `0` (`netuid 0` is not allowed). - - Integer values greater than the value of current subnet limit, i.e., greater than the value of `subtensorModule.subnetLimit()`, will be rejected with an error message and the command will stop. - - All child hotkeys used in this command must be already registered on this `netuid`. -- `--children`: SS58. A comma-separated ordered list of SS58 hotkeys for child hotkeys. - - There should be a maximum of five, 5, SS58 hotkeys in this comma-separated list. If there are more than five hotkeys, the command will issue an error message and stop. - - The number of list elements should match the number of elements passed in the `--proportions` parameter. If the number of list elements do not match, the command will issue an error and stop. - - All hotkeys used here must be already registered on the `netuid` used in this command. - -- `--proportions`: Floating. A comma-separated ordered list of floating values. Each proportion value of the parent hotkey's stake weight will be assigned to the corresponding child hotkey in the `--children` parameter. - - Each floating value should be a number greater than zero and equal to or less than `1.0`. - - If a value is zero, the corresponding child hotkey will be revoked. - - If a value is greater than `1.0`, the command will issue an error message and stop. - - All the proportions for a given `netuid` must sum to less than or equal to `1.0`. If the proportions sum to greater than `1.0`, the command will issue an error message and stop. -- `--hotkey`: SS58. A single SS58 of the parent hotkey. This must be a delegate hotkey that is already registered in with any `netuid`. This `netuid` need not be the same `netuid` used in this command. - - If this parent hotkey has zero stake, then the command will issue an error message and stop. - - Note that this `--hotkey` parameter expects parent hotkey whereas the `--hotkey` parameter of the [Setting child hotkey take](#parameters-1) expects child hotkey. -- `--wallet.name`: String or SS58. Name of the wallet or the SS58 of the coldkey. This coldkey must be matched with the parent hotkey SS58 of the `--hotkey`. If the coldkey and the parent hotkey do not match, the command will issue an error message and stop. - -### Examples - -#### Setting a single child hotkey - -```bash -btcli stake set_children \ - --netuid 4 \ - --children 5HEXVAHY9gyavj5xnbov9Qoba4hPJYkkwwnq1MQFepLK7Gei \ - --proportions 0.5 \ - --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ - --wallet.name Alice -``` - -#### Setting multiple child hotkeys - -```bash -btcli stake set_children \ - --netuid 4 \ - --children 5Gx1CZ9jviC6V2KynBAcTpES4yK76riCagv5o5SFFZFYXj4s,5HEXVAHY9gyavj5xnbov9Qoba4hPJYkkwwnq1MQFepLK7Gei \ - --proportions 0.3,0.7 \ - --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ - --wallet.name Alice -``` - -## Adding a new child hotkey - -If a parent hotkey has, for example, three child hotkeys: child hotkey A, child hotkey B and child hotkey C, then to add a fourth child hotkey D, you must run `set_children` command again with the parent hotkey and all four child hotkeys A, B, C and D. - -## Changing the proportions - -If a parent hotkey has, for example, three child hotkeys: - - child hotkey A with `0.2` proportion. - - child hotkey B with `0.5` proportion. - - child hotkey C with `0.1` proportion. - -Then to change the proportion of, for example, the child hotkey B from `0.5` to `0.3`, you must run `set_children` command again with the parent hotkey and all three child hotkeys A, B, and C set to `0.2`, `0.3` and `0.1` proportions. - - -## Getting the child hotkeys - -This command displays all the child hotkeys for a given parent hotkey. - -### Usage - -```bash -btcli stake get_children --netuid --hotkey --all -``` - -### Example - -```bash -btcli stake get_children \ - --netuid 4 \ - --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ - --wallet.name Alice \ - --all -``` - -or - -```bash -btcli stake get_children -``` -and follow the prompts. - -## Revoking the child hotkeys - -This command revokes **all** the child hotkeys for a given parent hotkey. - -:::danger Revoking a specific child hotkey is not allowed -Currently it is not possible to revoke a specific child hotkey. However, if a parent hotkey has, for example, three child hotkeys: child hotkey A, child hotkey B and child hotkey C, then setting the parent hotkey again with only child hotkeys A and B will result in revoking the child hotkey C. -::: - -### Usage - - -```bash -btcli stake revoke_children \ - --netuid \ - --hotkey \ - --wallet.name -``` - -### Example - -```bash -btcli stake revoke_children \ - --netuid 4 \ - --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ - --wallet.name Alice -``` - -or - -```bash -btcli stake revoke_children -``` -and follow the prompts. - -## Setting child hotkey take - -This command sets the take percentage of the child hotkey for a given `netuid`. The `take` can be between `0` (0%) and `0.18` (18%). - -A child hotkey's `take` is subnet-specific, i.e., a child hotkey can have one `take` in one `netuid` and a different `take` in another `netuid`. - -The child hotkey take rate is an attribute of the child hotkey and this take rate applies to all the parent hotkeys for which this hotkey is the child hotkey. - -The child hotkey can also set its delegate take separately from the child hotkey take. That is, a child hotkey can carry two separate take rates: the child hotkey take rate and the delegate take rate. For the delegate take rate, see [Set delegate take](../btcli.md#set-delegate-take). - -### Usage - -```bash -btcli stake set_childkey_take \ - --netuid \ - --hotkey \ - --take \ - --wallet.name -``` - -### Parameters - -- `--hotkey`: SS58. A single SS58 of the child hotkey. Note that this `--hotkey` parameter expects child hotkey whereas the `--hotkey` parameter of the [Setting a child hotkey](#parameters) expects parent hotkey. -- `--take`: Floating. A value between `0` (0%) and `0.18` (18%). Default value is `0`. -- `--netuid`: Integer. The `netuid` in which this child hotkey's `take` is applicable. Note that a child hotkey's `take` is subnet-specific, i.e., a child hotkey can have one `take` in one `netuid` and a different `take` in another `netuid`. - -### Example - -```bash -btcli stake set_childkey_take \ - --netuid 4 \ - --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ - --take 0.09 \ - --wallet.name Alice -``` - -## Getting child hotkey take - -This command displays the take percentage of a given child hotkey and `netuid`. - -### Usage - -```bash -btcli stake get_childkey_take \ - --netuid \ - --hotkey \ - --wallet.name -``` - - -### Example - -```bash -btcli stake get_childkey_take \ - --netuid 4 \ - --hotkey 5Gx1CZ9jviC6V2KynBAcTpES4yK76riCagv5o5SFFZFYXj4s \ - --wallet.name Bob -``` diff --git a/docs/subnets/commit-reveal.md b/docs/subnets/commit-reveal.md deleted file mode 100644 index 61158405bb..0000000000 --- a/docs/subnets/commit-reveal.md +++ /dev/null @@ -1,97 +0,0 @@ - -import ThemedImage from '@theme/ThemedImage'; -import useBaseUrl from '@docusaurus/useBaseUrl'; - -# Commit Reveal - -This page describes the **commit reveal** feature: a configurable waiting period that elapses between a) when consensus weights set by subnet validators are first committed, and b) when they are revealed publicly and included in Yuma Consensus. - -This feature was designed to address the issue of *weight copying* by validators. - -## Weight copying - -In each Bittensor subnet, each validator scores—or *'weights'*—each miner, producing what is referred to as a [weight vector](../glossary.md#weight-vector). The weight vectors for each validator in a subnet are combined into a weight matrix. This matrix determines emissions to miners in the subnet based on the consensus evaluation of their performance, according to [Yuma Consensus](../glossary.md#yuma-consensus). - -The weight matrix is public information, and must be, so that emissions in the Bittensor platform can be transparently fair. However, this transparency makes it possible for subnet validators to free-ride on the work of other validators by copying the latest consensus rather than independently evaluating subnet miners. This is unfair and potentially degrades the quality of validation work, undermining Bittensor's ability to incentivize the best miners and produce the best digital commodities overall. - -The commit reveal feature is designed to solve the weight copying problem by giving would-be weight copiers access only to stale weights. Copying stale weights should result in validators departing from consensus. However, it is critical to note that this only works if the consensus weight matrix changes sufficiently on the time scale of the commit reveal interval. If the demands on miners are too static, and miner performance is very stable, weight copying will still be successful. The only solution for this is to demand continuous improvement from miners, requiring them to continuously evolve to maintain their scoring. Combined with a properly tuned Commit Reveal interval, this will keep validators honest, as well as producing the best models. - -## Commit Reveal and Immunity Period - -The [Immunity Period](../glossary.md#immunity-period) is the interval (measured in blocks) during which a miner or validator newly registered on a subnet is 'immune' from deregistration due to performance. The duration of this period value should always be larger than the Commit Reveal interval, otherwise the immunity period will expire before a given miner's scores are available, and they may be deregistered without having their work counted. - -When creating a new subnet, ensure that the miner immunity period is larger than the commit reveal interval. When updating the immunity period or commit reveal interval hyperparameters for a subnet, use the following formula: - -``` -new_immunity_period = (new_commit_reveal_interval - old_commit_reveal_interval) + old_immunity_period -``` - -See [Subnet Hyperparameters](./subnet-hyperparameters.md). - -## Commit reveal in detail - -When commit reveal is enabled, it works as follows: - -1. A subnet validator sets the weights normally by using [`set_weights`](pathname:///python-api/html/autoapi/bittensor/core/extrinsics/set_weights/index.html). - -2. Instead of publishing weights openly, an encrypted copy of these weights is committed to the blockchain, using an internal method called [`commit_weights`](pathname:///python-api/html/autoapi/bittensor/core/extrinsics/commit_weights/index.html). - -3. A waiting interval, specified as a number of blocks, elapses. Subnet owners configure this interval with the subnet hyperparameter `commit_reveal_weights_interval`. - -4. After this interval has elapsed, the unencrypted weights are automatically revealed by the chain, using [Drand time-lock encryption](https://drand.love/docs/timelock-encryption/). - -5. The weights are now input to Yuma Consensus. - -
-:::tip Commit reveal works behind the scenes -After the subnet owner turns ON the commit reveal feature, everything happens behind the scenes. A subnet validator will continue to set weights normally by using [`set_weights`](pathname:///python-api/html/autoapi/bittensor/core/extrinsics/set_weights/index.html). -::: - -
- -
- - -## How to use the commit reveal feature - -As a subnet owner, set the below hyperparameters to use the commit reveal feature: - -1. `commit_reveal_weights_enabled` (boolean): Set this to `True` to activate the commit reveal feature for the subnet. Default value is `False`. -2. `commit_reveal_weights_interval` (int): Set this to an integer number. This is the number of subnet tempos to elapse before revealing the weights by submitting them again to the blockchain, but now openly for everyone to see. Default value is `1`. - -See [Setting subnet hyperparameters](subnet-hyperparameters#setting-the-hyperparameters). - -:::danger Ensure that the commit reveal interval is less than your immunity period to avoid unintended miner de-registration! -See [Commit Reveal and Immunity Period](#commit-reveal-and-immunity-period). -::: - - -Weights will be revealed immediately at the beginning of the tempo after the `commit_reveal_weights_interval`. For example, if `commit_reveal_weights_interval` value is set to `3`, then the reveal will occur at the beginning of the fourth tempo from the current tempo. The current tempo is counted as the first tempo. See the below diagram for this example: - -
- -
- -
- - -## Technical papers and blog - -- ACM CCS2024 Poster PDF [Solving the Free-rider Problem In Bittensor](pathname:///papers/ACM_CCS2024_Poster.pdf). -- See [Weight Copying in Bittensor, a technical paper (PDF)](pathname:///papers/BT_Weight_Copier-29May2024.pdf). -- Blog post, [Weight Copying in Bittensor](https://blog.bittensor.com/weight-copying-in-bittensor-422585ab8fa5). - diff --git a/docs/subnets/create-a-subnet.md b/docs/subnets/create-a-subnet.md index 983ea28092..0409bf349d 100644 --- a/docs/subnets/create-a-subnet.md +++ b/docs/subnets/create-a-subnet.md @@ -8,9 +8,10 @@ This page describes the procedures for creating a new Bittensor subnet on test c You should first try [Creating a Subnet on a locally deployed chain](../local-build/create-subnet). -Creating a subnet is a major undertaking. You should read up on [Understanding Subnets](understanding-subnets) and research existing subnets before planning to create one. +Creating a subnet is a major undertaking. You should read up on [Understanding Subnets](understanding-subnets) and research existing subnets before planning to create one. ## Considerations + ### Research existing subnets Prospective subnet creators should familiarize themselves with the space of existing subnets. @@ -20,7 +21,7 @@ Prospective subnet creators should familiarize themselves with the space of exis ### Burn cost -The burn cost for subnet creation is dynamic; it lowers gradually and doubles every time a subnet is created. +This refers to the required amount of TAO to be recycled when creating a new subnet. The burn cost for subnet creation is dynamic and reflects the current cost to register a new subnet. Its value lowers gradually and doubles every time a subnet is created. :::tip try it live @@ -33,19 +34,21 @@ Check the burn cost to create a subnet on Bittensor main network and test networ ```shell btcli subnet burn-cost --network finney ``` + ```shell btcli subnet burn-cost --network test ``` + ::: ### A new subnet is not automatically active -To allow subnet owners to fully set up their subnets and to prevent extraction of emissions to subnet participants before the subnet is contributing to the network, new subnets are inactive and cannot be started for 7 * 7200 blocks (roughly one week) after they are registered. During this time, you can register and activate validators and invite miners into the subnet. +To allow subnet owners to fully set up their subnets and to prevent extraction of emissions to subnet participants before the subnet is contributing to the network, new subnets are inactive and cannot be started for 7 \* 7200 blocks (roughly one week) after they are registered. During this time, you can register and activate validators and invite miners into the subnet. :::info The subnet and its participants will receive **no emissions** during the time that the subnet is inactive. @@ -55,7 +58,7 @@ The subnet and its participants will receive **no emissions** during the time th You must meet the same [requirements for validation](../validators#requirements-for-validation) as other validators in order to set weights in your own subnet. -One option for subnet owners is to ask one of the root network (subnet 0) validators to parent your validator hotkey as a childkey of theirs. This will lend their stake to your validator, and can help you ensure that your validator maintains a sufficient stake to effectively participate in consensus as well as resist deregistration. See the [Child Hotkeys](./child-hotkeys) documentation for more detail. +One option for subnet owners is to ask one of the root network (subnet 0) validators to parent your validator hotkey as a childkey of theirs. This will lend their stake to your validator, and can help you ensure that your validator maintains a sufficient stake to effectively participate in consensus as well as resist deregistration. See the [Child Hotkeys](../validators/child-hotkeys) documentation for more detail. ### Subnet creation rate limits @@ -64,7 +67,9 @@ Subnet creations are limited to **one subnet creation per 7200 blocks** (approxi ## Prerequisites - [Install the most recent version of BTCLI](../getting-started/install-btcli). -- [Created a wallet](../getting-started/wallets.md#creating-a-local-wallet). + +- [Create a wallet](../keys/working-with-keys#creating-a-wallet-with-btcli). + - To create a subnet on test chain, your wallet must have sufficient test net TAO. Inquire in [Discord](https://discord.com/channels/799672011265015819/1107738550373454028/threads/1331693251589312553) to obtain TAO on Bittensor test network. - To create a subnet on main network (finney) requires a substantial investment of TAO, depending on current registration cost for new subnets. @@ -75,9 +80,11 @@ Create your new subnet on the testchain using the test TAO you received from the Run the create subnet command on the testchain. ```bash -btcli subnet create --network test +btcli subnet create --network test ``` + Output: + ```bash # Enter the owner wallet name, which gives the coldkey permissions to define running hyperparameters later. >> Enter wallet name (default): owner # Enter your owner wallet name @@ -89,18 +96,20 @@ Output: ## Creating a subnet on mainchain -:::caution Alert: Minimum required TAO +:::caution Alert: Minimum required TAO Creating a subnet on the mainnet is competitive, and the cost is determined by the rate at which new networks are registered onto the chain. ::: -### Create the subnet +### Create the subnet -Use the below command to create a new subnet on the mainchain. +Use the below command to create a new subnet on the mainchain. ```bash btcli subnet create ``` + Output: + ```bash >> Enter wallet name (default): owner # Enter your owner wallet name >> Enter password to unlock key: # Enter your wallet password. @@ -111,7 +120,7 @@ Output: ### Check to see if you can start the subnet -Use the below command to check whether the subnet can be started. +Use the below command to check whether the subnet can be started. ```bash btcli subnet check-start --netuid x @@ -119,11 +128,11 @@ btcli subnet check-start --netuid x Where "x" is the subnet ID. -The output will provide you with the block registered and the block at which the subnet can be started, with "blocks remaining" and an estimated time. When this time has passed, the `check-start` command will return `Emission schedule can be started.` +The output will provide you with the block registered and the block at which the subnet can be started, with "blocks remaining" and an estimated time. When this time has passed, the `check-start` command will return `Emission schedule can be started.` ### Start the subnet -Use the below command to start the subnet once `check-start` returns `Emission schedule can be started.` +Use the below command to start the subnet once `check-start` returns `Emission schedule can be started.` ```bash btcli subnet start --netuid x diff --git a/docs/subnets/crowdloans/crowdloans-tutorial.md b/docs/subnets/crowdloans/crowdloans-tutorial.md new file mode 100644 index 0000000000..89fe6e1e22 --- /dev/null +++ b/docs/subnets/crowdloans/crowdloans-tutorial.md @@ -0,0 +1,305 @@ +--- +title: "Create a Subnet with a Crowdloan" +--- + +# Create a Subnet with a Crowdloan + +This page describes creating a subnet via **crowdloan** on a locally deployed Bittensor chain. We will use the Polkadot‑JS web app to submit extrinsics. + +See also [Crowdloans Overview](./index.md) + +The following steps will take us through the lifecycle of a subnet creation crowdloan: + +- First, we will **create** a crowdloan for a subnet. This is a special contract that will conditionally create the subnet if enough funds are raised (this threshold is called a crowdloan's **cap**). +- Next, we will **contribute** enough funds for the crowdloan to reach its cap. +- Next we must **finalize** the crowdloan, which executes the action wrapped inside the crowdloan—the creation of the subnet. +- Finally, we will verify the successful creation of the subnet by starting its emissions and observing the flow of liquidity to validator and creator hotkeys. + +## Prerequisites + +- A locally running subtensor development chain. For more information, see [run a local Bittensor blockchain instance](../../local-build/deploy.md). +- [Polkadot‑JS browser app](https://polkadot.js.org/apps/?#/explorer) and [Polkadot‑JS browser extension](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd) installed. +- An accessible 'Alice' wallet (see: [Provision Wallets for Local Deploy](../../local-build/provision-wallets)) + +## Step 1: Connect Polkadot‑JS to your local chain + +1. Open the Polkadot‑JS app. +2. In the network selector, choose Development → custom endpoint `ws://127.0.0.1:9944`. +3. Confirm your local chain metadata loads and your test accounts appear in the Accounts tab. To do this, see [create and import accounts to the Polkadot-JS extension](../../keys/multisig.md#create-and-import-3-coldkey-pairs-accounts-in-the-polkadot-js-browser-extension). + +:::tip +If the web app does not connect to your local chain, your browser’s privacy or security settings may be blocking it. Try adjusting those settings and reconnecting. +::: + +## Step 2: Generate call hash + +Before creating the crowdloan, you must first generate the hash that registers the subnet and creates a dedicated proxy for the designated beneficiary. +To begin: + +1. Go to **Developer** → **Extrinsics**. +2. Under “**using the selected account**”, pick the crowdloan "`creator`" account. +3. Under “**submit the following extrinsic**”, choose module `subtensorModule`, call `registerLeasedNetwork(emissionsShare, endBlock)`. +4. Fill the parameters: + + - `emissionsShare`: choose a percentage, e.g, 30. + - `endBlock`: leave as none. + +5. Copy the hex code shown in the **encoded call data** field. You will use this to create the crowdloan in the next step. + +:::info +Do not submit the transaction after entering the parameters. Only copy the encoded call data once all parameters are provided. +::: + +## Step 3: Create a crowdloan + +We will create a campaign whose purpose is to register a leased subnet on finalize. + +1. Go to **Developer** → **Extrinsics**. +2. Under “**using the selected account**”, pick the crowdloan "`creator`" account. +3. Under “**submit the following extrinsic**”, choose module `crowdloan`, call `create`. +4. Fill the parameters: + + - `deposit`: choose an amount (e.g., `10,000,000,000` = 10 TAO on default dev config) + - `min_contribution`: e.g., `100,000,000` (0.1 TAO) + - `cap`: e.g., `2,000,000,000,000` (2000 TAO) + - `end`: pick a block height in the near future (e.g., current + 5000) + - `call`: put the hex code of the encoded call data saved from the previous step. + - `target_address`: leave as **None**. + + :::info + + - Set the `cap` value higher than the projected subnet lock cost plus proxy deposit (and a small fee buffer). On most dev setups the baseline lock cost is 1,000 TAO (1,000,000,000,000 RAO). If `cap` equals the lock cost exactly, the lease coldkey may lack enough to pay proxy deposits and finalize can fail with insufficient balance. + - If your local subtensor node uses non-fast blocks, the minimum duration for a crowdloan is one week (≈ 50,400 blocks). Therefore, the `end` value must be set at least 50,400 blocks after the current block. This limitation also applies on testnet and mainnet. + ::: + +5. Click **Submit Transaction** and sign with the `creator` account. + +### Get the crowdloan ID + +Crowdloan IDs are allocated sequentially, starting from `0`, with each new crowdloan assigned the next incremental ID. There is no extrinsic to list created crowdloans. Therefore, to check the identity of crowdloans created, you must use one of these methods. + +- **From Events**: + + 1. Navigate to the **block explorer** after submitting the crowdload transaction. + 2. In the **Explorer** tab, find the block in which the transaction occured. + 3. In the **Events** panel, locate the `crowdloan.create` extrinsic. The `crowdloan.Created` event payload includes `crowdloanId` that represents the ID of the crowdloan. + +- **From storage**: + + 1. From the **Developer** dropdown, navigate to **Chain state** → **Storage**. + 2. Click the **selected state query** menu and select `crowdloan.nextCrowdloanId`. + 3. Click the **+** icon to run the query. + + :::tip + This query returns the ID assigned to the next crowdloan that will be created. Subtract 1 from the returned value to determine the total number of crowdloans that currently exist. + ::: + +- **From the JS console**: + 1. From the **Developer** dropdown, navigate to **Javascript**. + 2. Next, paste the following code block in the editor and run: + +```javascript +// List all existing crowdloan ids +const keys = await api.query.crowdloan.crowdloans.keys(); +console.log(keys.map((k) => k.args[0].toNumber())); +``` + +## Step 4: Contribute to the crowdloan + +All contributions must occur before the defined `end` block and will be clipped to the `cap` value provided. + +To contribute to the crowdloan, repeat the following steps for each contributor account: + +1. From the **Developer** dropdown, navigate to **Extrinsics** +2. Under “**using the selected account**”, select the crowdloan "contributor(s)" account. +3. Under “**submit the following extrinsic**”, choose module `crowdloan`, call `contribute (crowdloan_id, amount)`. +4. Provide the `crowdloan_id` (typically 0 on a fresh chain) and an amount. +5. Submit and sign. + +:::info + +The crowdloan cap is the maximum total raise. If a contribution would push the total above this cap, the contribution is clipped to fit the remaining available amount. Once the cap is reached, any further contributions are rejected and a `crowdloan.CapRaised` event is triggered. +::: + +### Verify crowdloan contributions + +To verify crowdload contributions: + +- **From Events**: + + 1. Navigate to the **block explorer** after contributing to the crowdload. + 2. In the **Explorer** tab, find the block in which the transaction occured. + 3. In the **Events** panel, locate the `crowdloan.contribute` extrinsic. The `crowdloan.Contributed` event payload contains the `crowdloanId`, the contributing account, and amount contributed. + +- **From storage**: + + 1. From the **Developer** dropdown, navigate to **Chain state** → **Storage**. + 2. Click the **selected state query** menu and select one of the following: + + - `crowdloan.Crowdloans(crowdloan_id)` to check details of the crowdloan + - `crowdloan.Contributions(crowdloan_id, contributor)` to check contributions by an account. + + 3. Click the **+** icon to run the query. + +## Step 5: Finalize the crowdloan + +The crowdload can be finalized by the creator when the end block has passed and the cap has been fully raised (`raised == cap`). + +1. Wait for the chain to reach the `end` block. +2. From the **Developer** dropdown, go to **Extrinsics**. +3. Under **using the selected account**, select the crowdloan creator account. +4. Select `crowdloan.finalize(crowdloan_id)` and put the ID of the crowdload. +5. Submit and sign. + +
+Show Event Output +``` +system.ExtrinsicSuccess +balances.Withdraw (x2) +system.NewAccount (x2) +balances.Endowed +balances.Transfer (x2) +subtensorModule.RegistrationAllowed +subtensorModule.MaxAllowedUidsSet +subtensorModule.MaxAllowedValidatorsSet +subtensorModule.MinAllowedWeightSet +subtensorModule.MaxWeightLimitSet +subtensorModule.AdjustmentIntervalSet +subtensorModule.RegistrationPerIntervalSet +subtensorModule.AdjustmentAlphaSet +subtensorModule.ImmunityPeriodSet +subtensorModule.MinDifficultySet +subtensorModule.MaxDifficultySet +subtensorModule.NetworkAdded +balances.Reserved +proxy.ProxyAdded +subtensorModule.SubnetLeaseCreated +crowdloan.Finalized +balances.Deposit +transactionPayment.TransactionFeePaid +extrinsic event +``` +
+ +:::info + +- Even if the `cap` has been raised, the crowdloan cannot be finalized before the `end` block. Finalizing before the contribution period ends fails with a `ContributionPeriodNotEnded` event. +- If `target_address` was provided, the raised amount is transferred there. +- The stored `subtensor.register_leased_network` call executes with creator origin, and the subnet lease is created. +- The created subnet lease includes the coldkey and hotkey of the proxy wallet that manages the subnet. See [Get the lease coldkey](#get-the-lease-coldkey). + ::: + +### Verify the leased subnet + +Finalizing the crowdloan registers a new subnet and creates a dedicated proxy for the designated beneficiary. Use one of the following methods to verify the creation of the leased subnet: + +- **Using BTCLI**: + + You can verify the creation of the new subnet by running the following command in your terminal: + + ```sh + btcli subnets list --network local + ``` + + This command lists all created subnets on the chain. Notice the addition of a new subnet among the listed subnets—netuid `2` in the following output. + +
+Show Sample Output + +```console +Using the specified network local from config +[15:49:40] Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:89 + + Subnets + Network: local + + + ┃ ┃ Price ┃ Market Cap ┃ ┃ ┃ ┃ ┃ +Netuid ┃ Name ┃ (Τ_in/α_in) ┃ (α * Price) ┃ Emission (Τ) ┃ P (Τ_in, α_in) ┃ Stake (α_out) ┃ Supply (α) ┃ Tempo (k/n) +━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━ + 0 │ τ root │ 1.0000 τ/Τ │ τ 0.00 │ τ 0.0000 │ -, - │ Τ 0.00 │ 0.00 Τ /21M │ -/- + 2 │ β omron │ 0.0000 τ/β │ τ 0.00 │ τ 0.0000 │ τ 1.00k, 1.00k β │ 0.00 β │ 1.00k β /21M │ 3/10 + 1 │ α apex │ 0.0000 τ/α │ τ 0.00 │ τ 0.0000 │ τ 10.00, 10.00 α │ 1.00 α │ 11.00 α /21M │ 28/100 +────────┼───────────┼─────────────┼─────────────┼──────────────┼────────────────────────┼───────────────┼──────────────┼───────────── + 4 │ │ τ 0.0 │ │ τ 0.0 │ τ 2.01k/20.93k (9.60%) │ │ │ + +``` + +
+ +## Step 6: Start the leased subnet (via proxy) + +Before starting the subnet, you must first get the address of the proxy wallet specified in the subnet lease, as this wallet controls the subnet. + +#### **Get the lease coldkey** + +1. From the **Developer** dropdown, navigate to **Chain state** → **Storage**. +2. Click the **selected state query** menu and select `subtensorModule.SubnetLeases(lease_id)` to display details of the subnet lease, including the beneficiary, emission share, end block, lease coldkey and hotkey, netuid, and creation cost. +3. Click the **+** icon to run the query. +4. Copy the value of the `lease.coldkey` in the response. You can add the lease coldkey to the address book on the Polkadot.js web app so that it's selectable in the UI. + +:::tip + +- In your local environment, the `lease_id` would be the same as the ID of the crowdloan created. You can confirm the `lease_id` by examining the block where the subnet lease was created for a `subtensorModule.SubnetLeaseCreated` event. + + ::: + +Next, follow the following steps to start the subnet: + +1. Go to **Developer** → **Extrinsics**. +2. Under “**using the selected account**”, pick the crowdloan "`creator`" account. +3. Under “**submit the following extrinsic**”, choose module `proxy`, call `proxy(real, forceProxyType, call)`. +4. Fill the parameters: + + - `real`: enter the `lease.coldkey` gotten from the previous query. + - `forceProxyType`: click the toggle and then choose the `SubnetLeaseBeneficiary`option in the dropdown. + - `call`: choose `subtensorModule.start_call` and then enter the netuid of the subnet you want to start. + - Submit and sign. + +## Observe dividends distribution + +Emissions accrue in Alpha (subnet share units), but are distributed in TAO. On distribution, the contributors' alpha is unstaked/swapped to TAO using the subnet pool; if swap/unstake cannot proceed (liquidity/price), the alpha is accumulated for later. + +Owner emissions are periodically split among contributors and the beneficiary, but only when all of these are true: + +- The subnet is leased and active (lease has not ended). +- A coinbase cycle paid an owner cut to the subnet owner for the given `netuid`. +- Current block is an exact multiple of `LeaseDividendsDistributionInterval` (check in Constants). +- There is sufficient liquidity to unstake the contributors’ cut from the subnet at or above the minimum swap price. + +Balances credited go to each contributor’s coldkey and the beneficiary’s coldkey. You can observe changes by querying balances over time. + +## Alternative path: Refund and dissolve + +If the cap is not reached by `end`: + +1. Anyone can call `crowdloan.refund(crowdloan_id)` repeatedly until all contributors (except the creator) are refunded (batched per call). +2. After refunds complete (only the creator’s deposit remains), the `creator` can call `crowdloan.dissolve(crowdloan_id)` to clean up and recover the deposit. + +### Optional: Withdraw + +Before finalization: + +- Any contributor can `crowdloan.withdraw(crowdloan_id)` to recover their contribution. +- The creator can only withdraw amounts above the kept deposit; the deposit itself remains until refund/dissolve. + +## Troubleshooting + +- Call fails with `InvalidCrowdloadId` + - Ensure that the crowdloan ID exists. +- Call fails with `InvalidOrigin` + - Ensure that the selected account that is responsible for signing the transaction. +- Call fails with `BlockDurationTooShort` + - Ensure that the crowdloan `end` is set at least one week away—~50,400 blocks. +- Call fails with `BlockDurationTooLong` + - Ensure that the crowdloan `end` is set between a week to 2 months away. +- Contribution call fails with `ContributionPeriodEnded` + - Extend the `end` value on the crowdloan using the `crowdloan.updateEnd` extrinsic. +- Finalize fails with `CapNotRaised` + - Ensure total `raised` equals `cap`. Add contributions or adjust `cap` via `update_cap` (creator‑only) before `finalize`. +- Finalize fails with `ContributionPeriodNotEnded` + - Wait until the `end` block is reached. +- Finalize fails with `CallUnavailable` + - Ensure the nested call was supplied during `create`. The pallet stores it as a preimage; if unavailable, it errors and drops the reference. +- Refund does nothing + - Refunds only after `end` and only for non‑finalized campaigns. It processes up to `RefundContributorsLimit` contributors per call. diff --git a/docs/subnets/crowdloans/index.md b/docs/subnets/crowdloans/index.md new file mode 100644 index 0000000000..82e071d56a --- /dev/null +++ b/docs/subnets/crowdloans/index.md @@ -0,0 +1,120 @@ +--- +title: "Crowdloans" +--- + +### Overview + +The crowdloan feature lets a group of people collectively fund an extrinsic execution or a balance transfer to a specific address. For example, it can be used to fund the registration of a new Bittensor subnet and share the resulting emissions according to each person's contribution. Instead of a single sponsor paying the full lease cost up front, a creator opens a crowdloan with a funding cap and end block, contributors deposit funds until the cap is met, and—on success—the pallet finalizes the crowdloan by funding subnet registration and activating emissions for the group. + +At finalization, the system executes an on‑chain call—typically `subtensor::register_leased_network`—using the crowdloan's funds. This registers the subnet and creates a dedicated proxy, `SubnetLeaseBeneficiary`, for the designated beneficiary (the crowdloan creator). That proxy is authorized to operate the subnet (for example, configuring subnet parameters and other allowed controls) without having custody of contributor funds or emissions splits. + +If the crowdloan is finalized and a lease is created, emissions flow to contributors pro‑rata based on their contributed share. If the crowdloan is not finalized after the end block, anyone can call refunds; once all contributors are refunded, the creator can dissolve the crowdloan. The call and target address specified at creation are immutable, ensuring that the purpose of the crowdloan cannot be changed mid‑campaign. This model makes subnet bootstrapping collaborative, transparent, and permissioned through a narrowly scoped proxy for safe, ongoing operations. + +Design features: +- Strong defaults: immutable target and call, capped funding, clear end block +- Shared upside: emissions distributed proportionally to contributions +- Safe operations: a dedicated proxy to manage the subnet within defined permissions + +:::info +**Crowdloans** and **Leasing** are two different but related concepts: + +**Crowdloan** enables someone to fund some extrinsic execution or a balance transfer at some end date, with contributors able to participate to a cap. When finalized, this will execute the extrinsic (substrate defined logic where we can move the funds and do something else) or transfer the balance to an address (EVM smart contract address for example). + +**Leasing** is split profit ownership of a subnet. This is tightly coupled to Crowdloan because a lease can only be created through a Crowdloan where the crowdloan extrinsic will be the `register_leased_network`. The logic to create a lease uses the contributors from the crowdloan as the lease shareholders, and the crowdloan creator as the lease beneficiary. Parameters like the lease end block and lease emissions shares are defined when you create the crowdloan. +::: + +See also [Create a Subnet with a Crowdloan](./crowdloans-tutorial.md) + +## Crowdloan Lifecycle + +- **Create** a campaign with deposit, cap, end, min contribution, optional `call` and `target_address`. [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/crowdloan/src/lib.rs#L318-L326) + +- **Contribute** funds; amounts are clipped to remaining cap; contributors are counted. [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/crowdloan/src/lib.rs#L413-L420) + +- **Withdraw** before finalization; creator cannot withdraw below their deposit. [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/crowdloan/src/lib.rs#L505-L525) + +- **Finalize** after end when cap is fully raised. Optionally transfers to `target_address` and dispatches the stored `call`. [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/crowdloan/src/lib.rs#L566-L581) + +- **Refund** loop refunds up to `RefundContributorsLimit` per call; may need multiple calls. [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/crowdloan/src/lib.rs#L637-L646) + +- **Dissolve** after refunds; creator's deposit is returned and storage cleaned up. [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/crowdloan/src/lib.rs#L711-L721) + +- **Update** parameters while crowdloan is running (creator only): + - `update_min_contribution` - adjust minimum contribution amount + - `update_end` - extend the end block + - `update_cap` - adjust the funding cap + +## Emissions distribution during a lease + +- When owner rewards are paid to a leased subnet, they are split into contributor dividends and a beneficiary cut. [Source code](https://github.com/opentensor/subtensor/blob/81ee047fd124f8837555fd79e8a3957688c5b0c6/pallets/subtensor/src/subnets/leasing.rs#L250) + +- Distribution is pro‑rata by recorded share; any remainder goes to the beneficiary. A lease can be created with an emissions share from 0 to 100%, which determines the share distributed to contributors. For example, if the emissions share is 50%, it means that 50% of the owner cut (18% currently) so 9% will be split proportionally to their share to contributors. [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/leasing.rs#L324-L339) + +## Operating the leased subnet via proxy + +- On successful registration, a `SubnetLeaseBeneficiary` proxy is added from the lease coldkey to the beneficiary. This proxy can call a narrowly scoped set of operations to operate the subnet. [Source code](https://github.com/opentensor/subtensor/blob/main/runtime/src/lib.rs#L886-L907) + +- Allowed calls for `ProxyType::SubnetLeaseBeneficiary` include starting subnet calls and selected admin‑utils setters (hyperparameters), not unrestricted sudo. [Source code](https://github.com/opentensor/subtensor/blob/main/runtime/src/lib.rs#L792-L852) + +## Runtime parameters (defaults) + +These constants define crowdloan requirements and operational limits in the runtime: [Source code](https://github.com/opentensor/subtensor/blob/main/runtime/src/lib.rs#L1556-L1571) + +Implications: + +- **Refund batching**: Up to 50 contributors are processed per `refund` call. +- **Duration bounds**: Ensures campaigns are neither too short nor too long. +- **Contribution floor**: Enforces a minimum "ticket size" for contributors. + +## FAQ + +### What problem do crowdloans solve? + +Crowdloans enable someone to fund some extrinsic execution or a balance transfer at some end date, with contributors able to participate to a cap. When finalized, this will execute the extrinsic (substrate defined logic where we can move the funds and do something else) or transfer the balance to an address (EVM smart contract address for example). + +Leasing is defined as split profit ownership of a subnet. This is tightly coupled to Crowdloan because a lease can only be created through a Crowdloan where the crowdloan extrinsic will be the "register_leased_network". The logic to create a lease will use the contributors from the crowdloan as the lease shareholders, the lease beneficiary will be crowdloan creator. Parameters like lease end block (some block in the future, probably much farther than crowdloan end) or lease emissions share are defined when you create the crowdloan and you pass the register_lease_network call with the parameters filled. + +### How does the end‑to‑end flow work? + +Creator calls `create` with deposit, cap, end, and a `call` of `subtensor::register_leased_network`. Contributors fund until the cap is hit. After the end block, creator calls `finalize`; funds transfer and the stored call executes with creator origin. A subnet and a `SubnetLeaseBeneficiary` proxy are set up; contributor shares are recorded, leftover cap is refunded. + +### Can the purpose of a crowdloan be changed after it starts? + +No. The `call` and optional `target_address` are bound at creation and used at `finalize`. The pallet exposes `CurrentCrowdloanId` only during dispatch to the called extrinsic, preventing mid‑campaign repurposing. + +### Who can finalize a crowdloan and when? + +Only the creator, after the end block, and only if `raised == cap` and it hasn’t already been finalized. + +### What happens if the cap is not reached? + +Anyone can call `refund` to batch‑refund contributors (excluding the creator) up to `RefundContributorsLimit` per call. After all refunds, only the creator can `dissolve` to recover the deposit and clean storage. + +### How are emissions split during a lease? + +Owner rewards are split to contributors by their recorded `SubnetLeaseShares`; any remainder goes to the beneficiary. The emissions are swapped for TAO and TAO is distributed to the contributors, not alpha. This runs automatically during coinbase distribution. + +### What permissions does the beneficiary proxy have? + +They can invoke a curated set of calls (e.g., start subnet calls and selected admin‑utils setters like difficulty, weights, limits). + + +### Can the campaign parameters be updated mid‑flight? + +The creator can update `min_contribution`, `end`, and `cap` on a non‑finalized crowdloan, subject to checks (duration bounds, cap >= raised, etc.). The `call` and `target_address` are immutable. + +### Is there a maximum number of contributors? + +Yes. `MaxContributors` limits unique contributors per crowdloan; contributions beyond that will be rejected. + +### How are leftover funds handled at lease creation? + +Any leftover cap (after paying registration + proxy cost) is refunded to contributors; the residual remainder goes to the beneficiary. + +### How do I track my expected emissions? + +Your share equals your contribution divided by total raised at `finalize`. Emissions are distributed to your coldkey during the lease according to that share. + +### Can a lease be terminated early? + +No. The beneficiary may terminate only after the optional `end_block` has passed; for perpetual leases there is no end block. diff --git a/docs/subnets/managing-mechanisms-btcli.md b/docs/subnets/managing-mechanisms-btcli.md new file mode 100644 index 0000000000..c962ada776 --- /dev/null +++ b/docs/subnets/managing-mechanisms-btcli.md @@ -0,0 +1,156 @@ +--- +title: "Managing Multiple Incentive Mechanisms with BTCLI" +--- + +# Managing Multiple Incentive Mechanisms with BTCLI + +This tutorial shows how to configure and manage multiple incentive mechanisms in a single subnet using BTCLI. + +For a discussion of the background concepts, see [Understanding Multiple Incentive Mechanisms](understanding-multiple-mech-subnets). + +See also: [Managing Mechanisms with SDK](managing-mechanisms-with-sdk). + +:::tip Hot new feature +Multiple incentive mechanisms per subnet is a new feature that is still in development. It's initial release on mainnet is expected the week of September 22. In the meantime, it can be experimented with using a locally run chain. + +See [Announcements](../learn/announcements) for updates. +::: + +**Prerequisites** +- A local Subtensor chain running. See: [Run a Local Bittensor Blockchain Instance](../local-build/deploy) +- A local subnet created (and emissions started). See: [Create a Subnet (Locally)](../local-build/create-subnet) +- Wallets provisioned and funded for local development. See: [Provision Wallets](../local-build/provision-wallets) +- BTCLI installed (development version required for mechanism commands) + +:::tip +Substitute your subnet's netuid, which you can find with `btcli subnet list`. +::: + +:::warning Runtime limit +As of the current Subtensor runtime, a subnet can have a maximum of 2 mechanisms. Attempts to set a higher count will be rejected by the chain (runtime enforces `MaxMechanismCount = 2`). + +::: + +## Check initial state + +The following command will check the count of your subnet's incentive mechanisms and display the emissions split among them. + + +```bash +btcli subnet mech count --netuid 6 --network local +btcli subnet mech emissions --netuid 6 --network local +``` +``` +Subnet 6 currently has 1 mechanism. +(Tip: 1 mechanism means there are no mechanisms beyond the main subnet) + +Subnet 6 only has the primary mechanism (mechanism 0). No emission split to display. +``` + +## Create a second mechanism + +Create a second incentive mechanism by specifying the desired count as two for your subnet. + +```bash +btcli subnet mech set --mech-count 2 --netuid 6 --network local +``` +``` +Subnet 6 currently has 1 mechanism. Set it to 2? [y/n]: y +✅ Mechanism count set to 2 for subnet 6 +``` + + +Check the state to confirm the change + +```bash +btcli subnet mech count --netuid 6 --network local +btcli subnet mech emissions --netuid 6 --network local +``` +``` +Subnet 6 currently has 2 mechanisms. +(Tip: 1 mechanism means there are no mechanisms beyond the main subnet) +[13:44:15] Warning: Verify your local subtensor is running on port 9944. subtensor_interface.py:85 + + Subnet 6 • Emission split + Network: local + + Mechanism Index Weight (u16) Share (%) + ───────────────────────────────────────────── + 0 32768 50.000763 + 1 32767 49.999237 + Total 65535 100.000000 + ───────────────────────────────────────────── + + +Totals are expressed as a fraction of 65535 (U16_MAX). +No custom split found; displaying an even distribution. +``` + + +## Set a custom 90/10 emission split + +Let's allocate only 10% of our subnet's emissions to the second subnet. + + +```bash +btcli subnet mech emissions-split --netuid 6 --network local --split "90,10" --wallet-name alice +``` +``` + Subnet 6 • Emission split + Network: local + + Mechanism Index Weight (u16) Share (%) + ───────────────────────────────────────────── + 0 32768 50.000763 + 1 32767 49.999237 + Total 65535 100.000000 + ───────────────────────────────────────────── + + +Totals are expressed as a fraction of 65535 (U16_MAX). +No custom split found; displaying an even distribution. + + Proposed emission split + Subnet 6 + + Mechanism Index Weight (u16) Share (%) + ───────────────────────────────────────────── + 0 58982 90.000000 + 1 6553 10.000000 + + Total 65535 100.000000 + ───────────────────────────────────────────── + + +Proceed with these emission weights? [y/n] (y): y +🌍 📡 Setting emission split for subnet 6... +✅ Emission split updated for subnet 6 +``` + + +We can confirm this by running the getter command again: + +```bash +btcli subnet mech emissions --netuid 6 --network local +``` +``` + + Subnet 6 • Emission split + Network: local + + Mechanism Index Weight (u16) Share (%) + ───────────────────────────────────────────── + 0 58982 90.000763 + 1 6553 9.999237 + Total 65535 100.000000 + ───────────────────────────────────────────── + + +Totals are expressed as a fraction of 65535 (U16_MAX). +``` + +## Troubleshooting + +- Rate limiting: mechanism count changes are restricted (on mainnet) to once per ~24 hours (7200 blocks). See [Rate Limits in Bittensor](../learn/chain-rate-limits.md). +- Permissions: emission split and count updates require the subnet owner wallet. +- Local chain connectivity: ensure your local chain is running and the `network` parameter in your BTCLI config is set to `local`. diff --git a/docs/subnets/managing-mechanisms-with-sdk.md b/docs/subnets/managing-mechanisms-with-sdk.md new file mode 100644 index 0000000000..97e38be14b --- /dev/null +++ b/docs/subnets/managing-mechanisms-with-sdk.md @@ -0,0 +1,165 @@ +--- +title: "Managing Multiple Incentive Mechanisms with SDK" +--- + +# Managing Multiple Incentive Mechanisms with SDK + +This tutorial shows how to configure and manage multiple incentive mechanisms in a single subnet using the Bittensor Python SDK. + +For background on the concepts, see [Understanding Multiple Incentive Mechanisms](./understanding-multiple-mech-subnets). + +See also [Managing Mechanisms with BTCLI](./managing-mechanisms-btcli). + +:::tip Hot new feature +Multiple incentive mechanisms per subnet is a new feature that is still in development. It's initial release on mainnet is expected the week of September 22. In the meantime, it can be experimented with using a locally run chain. + +See [Announcements](../learn/announcements) for updates. +::: + +**Prerequisites** +- A local Subtensor chain running. See: [Run a Local Bittensor Blockchain Instance](../local-build/deploy) +- A local subnet created (and emissions started). See: [Create a Subnet (Locally)](../local-build/create-subnet) +- Wallets provisioned and funded for local development. See: [Provision Wallets](../local-build/provision-wallets) +- BTCLI installed (development version required for mechanism commands) + + +:::tip +Substitute your subnet's netuid, which you can find with `btcli subnet list`. +::: + +:::warning Runtime limit +As of the current Subtensor runtime, a subnet can have a maximum of 2 mechanisms. Attempts to set a higher count will be rejected by the chain (runtime enforces `MaxMechanismCount = 2`). +::: + + +## Initialize SDK and wallet + +The following snippet initializes the Bittensor SDK, imports the needed modules, connects to the local blockchain, and initializes the wallet object for the Alice wallet. + +Run this at the top of each script below. + +```python +import bittensor as bt +from bittensor.core.extrinsics.sudo import ( + sudo_set_mechanism_emission_split_extrinsic, + sudo_set_mechanism_count_extrinsic, +) + +# Connect to local chain +subtensor = bt.Subtensor(network="local") + +# Load the subnet owner wallet (assumes wallet is provisioned locally) +wallet = bt.Wallet(name="alice") + +netuid = 7 +print("SDK version:", bt.__version__) +print(f"Connected to {subtensor.network} — managing subnet {netuid} with wallet {wallet.name}") +``` + +```text +SDK version: 9.10.1 +Connected to local — managing subnet 7 with wallet alice +``` + +## Read current mechanism configuration + +Add the below snippet to display the current mechanism count on subnet 7 (or whatever subnet you have set above). + +```python +# Mechanism count +mech_count = subtensor.get_mechanism_count(netuid=netuid) +print(f"Subnet {netuid} mech count: {mech_count} ") + +# Current emission split (chain-stored values) +raw_split = subtensor.get_mechanism_emission_split(netuid=netuid) + +# Normalize to percentages by sum (works for either u16-scaled or raw values) +if not raw_split == None: + _total = max(1, sum(raw_split)) + percentages = [round((v / _total) * 100, 6) for v in raw_split] + print("Percentages:", percentages) +else: + print("No split defined.") +``` + +``` +Subnet 7 mech count: 1 +No split defined. +``` + + +## Create a second mechanism + +Use the sudo extrinsic to increase the mechanism count to 2 for your subnet owner wallet. + +```python +# Increase mechanism count to 2 +ok, err = sudo_set_mechanism_count_extrinsic( + subtensor=subtensor, + wallet=wallet, + netuid=netuid, + mech_count=2, +) +print("Set mech count success:", ok) +if not ok: + print("Error:", err) + +# Verify the change +new_count = subtensor.get_mechanism_count(netuid=netuid) +print(f"Subnet {netuid} mech count (after): {new_count}") + +# Read split again; if None, display implied equal distribution +split_after = subtensor.get_mechanism_emission_split(netuid=netuid) + +print("split:") +print(split_after) +``` + +```text +Set mech count success: True +Subnet 7 mech count (after): 2 +split: +[50, 50] +``` + +## Set a custom 60/40 emission split + +```python +new_split = [60, 40] + +ok, err = sudo_set_mechanism_emission_split_extrinsic( + subtensor=subtensor, + wallet=wallet, + netuid=netuid, + maybe_split=new_split, +) + +print("Update success:", ok) +if not ok: + print("Error:", err) +``` + +```text +Update success: True + + +``` + +## Verify the change + +```python +split_after = subtensor.get_mechanism_emission_split(netuid=netuid) +print("split:") +print(split_after) +``` + +```text +split: +[60, 40] +``` + +## Troubleshooting + +- Rate limiting: mechanism count changes are restricted (on mainnet) to once per ~24 hours (7200 blocks). See [Rate Limits in Bittensor](../learn/chain-rate-limits.md). +- Permissions: emission split and count updates require the subnet owner wallet. +- Local chain connectivity: ensure your local chain is running and your SDK points to `network="local"`. diff --git a/docs/subnets/metagraph.md b/docs/subnets/metagraph.md new file mode 100644 index 0000000000..57707dc0e8 --- /dev/null +++ b/docs/subnets/metagraph.md @@ -0,0 +1,958 @@ +--- +title: "The Subnet Metagraph" +--- + +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Subnet Metagraph + +This page documents the Bittensor subnet metagraph. + +The **metagraph** is a core data structure in Bittensor that represents the complete state of a subnet at any given block. It contains comprehensive information about all neurons (miners and validators) participating in a subnet, their emissions, bonds, and trust, as well as subnet metrics. + +:::info source code +The metagraph is implemented in the Bittensor blockchain (Subtensor) as a Rust data structure. The source code is located in the [Subtensor repository](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/rpc_info/metagraph.rs). +::: + +Related reading: + +- [Understanding Neurons](../learn/neurons.md) +- [Subnet Hyperparameters](./subnet-hyperparameters.md) +- [Bittensor CLI Reference](../btcli/btcli.md) +- [Metagraph Precompile](../evm-tutorials/metagraph-precompile.md) + +## Accessing the Metagraph + +You can access metagraph data through multiple interfaces: + +### Bittensor CLI (btcli) + +The `btcli` command-line interface provides access to a subset of metagraph information (corresponding to "lite" mode in the SDK). For full metagraph data including weights and bonds, use the Python SDK with `lite=False`. + + + +```bash +# Dump metagraph subset to file (lite mode) +btcli subnets metagraph --netuid 14 --network finney \ + --json-output > sn14_metagraph.json + +# View abridged metagraph +btcli subnets metagraph --netuid 14 --network finney +``` + +```console + Subnet 14: TAOHash + Network: finney + + UID ┃ Stake (ξ) ┃ Alpha (ξ) ┃ Tao (τ) ┃ Dividends ┃ Incentive ┃ Emissions (ξ) ┃ Hotk… ┃ Coldkey ┃ Identity +━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━ + 29 │ 271.67k ξ │ 254.83k ξ │ τ 16.84k │ 0.129183 │ 0.000000 │ 19.122456 ξ │ 5Cf4… │ 5CKhH8 │ Owner14 (*Owner) + 3 │ 387.08k ξ │ 61.46k ξ │ τ 325.62k │ 0.184314 │ 0.000000 │ 27.280861 ξ │ 5C59… │ 5GZSAg │ + +... +``` + +:::note btcli Limitations +The btcli output shows a subset of metagraph data (lite mode). For complete data including ranks, trust scores, weights, and bonds, use the Python SDK with `lite=False`. +::: + +### Python SDK + +The Bittensor Python SDK [Metagraph module](pathname:///python-api/html/autoapi/bittensor/core/metagraph/index.html) provides programmatic access to metagraph data: + +```python +from bittensor.core.metagraph import Metagraph + +# Initialize metagraph for subnet 14 (lite mode - excludes weights/bonds) +m = Metagraph(netuid=14, network="finney", sync=True) + +# Initialize metagraph with full data including weights and bonds +m = Metagraph(netuid=14, network="finney", lite=False, sync=True) +``` + +### Mechanism-aware metagraphs (multiple incentive mechanisms) + +Subnets can run multiple incentive mechanisms. The SDK supports selecting a mechanism and exposes mechanism-related fields: + +- Metagraph accepts a `mechid` parameter (default `0`). +- New fields: `mechid: int`, `mechanisms_emissions_split: list[int]`, `mechanism_count: int`. + +```python +from bittensor.core.metagraph import Metagraph + +# Default mechanism (0) +meta = Metagraph(netuid=14, network="finney", sync=True) +print(meta.mechid) # 0 +print(meta.mechanism_count) # e.g., 2 +print(meta.mechanisms_emissions_split) # e.g., [60, 40] + +# Specific mechanism (1) +mech_meta = Metagraph(netuid=14, network="finney", sync=True, lite=False) +mech_meta.mechid = 1 +await mech_meta.sync() # or re-init with mechid in helper constructors +``` + +See also: [Multiple Incentive Mechanisms Within Subnets](./understanding-multiple-mech-subnets.md). + +### Smart Contract Access (Metagraph Precompile) + +For smart contract integration, you can access metagraph data through the **Metagraph Precompile** at address `0x0000000000000000000000000000000000000802`. This provides read-only access to individual neuron metrics and network information. + +:::tip Smart Contract Integration +For detailed smart contract examples and complete ABI, see the [Metagraph Precompile](../evm-tutorials/metagraph-precompile.md) documentation. +::: + +### RPC Functions + +The blockchain provides several RPC functions for accessing metagraph data: + +- `get_metagraph(netuid)` - Returns complete metagraph for a subnet +- `get_all_metagraphs()` - Returns metagraphs for all subnets +- `get_selective_metagraph(netuid, indexes)` - Returns partial metagraph data + +See [Subtensor:Metagraph RPC source code](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/rpc_info/metagraph.rs) + +## Performance Considerations + +### Lite vs Full Sync + +- **Lite Mode** (`lite=True`): Faster sync, excludes weights and bonds (corresponds to btcli output) +- **Full Mode** (`lite=False`): Complete data including weight matrices and bond matrices + +### Caching + +The metagraph supports local caching to persistent files: + +```python +# Save metagraph for later use +metagraph.save() + +# Load cached metagraph +metagraph.load() + +# Custom save directory +metagraph.save(root_dir=['/custom', 'path']) +``` + +:::info Cache Location +Metagraph files are saved to `~/.bittensor/metagraphs/network-{network}/netuid-{netuid}/block-{block_number}.pt` by default. The files are persistent and not temporary. + +**Source**: [`bittensor/bittensor/core/metagraph.py:96-115`](https://github.com/opentensor/bittensor/blob/main/bittensor/core/metagraph.py#L96-L115) +::: + +## Data Structures + +### Metagraph Object + +In the Bittensor Python SDK, the `Metagraph` class encapsulates the following information about a particular subnet. + +[Metagraph class specification, SDK reference](pathname:///python-api/html/autoapi/bittensor/core/metagraph/index.html) + + +
+ Metagraph Properties +| Name | Description | +|------|--| +| `netuid` | The subnet's unique identifier within the Bittensor network | +| `network` | Name of the Bittensor network, i.e. mainnet ('finney'), test, or a locally deployed chain | +| `version` | Bittensor version number | +| `n` | Total number of neurons registered on the subnet | +| `block` | Block number when the metagraph record was retrieved | +| `total_stake` | Total [stake weight](../resources/glossary.md#stake-weight) (α + τ × 0.18) across all neurons | +| **Stake** / `S` | Total [stake weight](../resources/glossary.md#stake-weight) (α + τ × 0.18) of each neuron, determining consensus power and emissions | +| **Alpha Stake** / `AS` | Alpha token stake (α) for each neuron | +| **Tao Stake** / `TS` | [TAO](../resources/glossary.md#tao-tau) token stake (τ) for each neuron | +| **Ranks** / `R` | Final performance scores after [consensus](../resources/glossary.md#consensus-score) weight clipping - [stake-weighted](../resources/glossary.md#stake-weight) sum of clipped weights that directly determine emissions to miners | +| **Trust** / `T` | [Consensus alignment](../resources/glossary.md#trust) ratio (final rank / pre-rank) - measures how much consensus clipping affected the rank, where 1.0 indicates perfect consensus alignment | +| **Validator Trust** / `Tv` | [Validator trust](../resources/glossary.md#validator-trust) - sum of clipped weights set by each validator, measuring validator influence in consensus | +| **Consensus** / `C` | [Consensus score](../resources/glossary.md#consensus-score) - stake-weighted median of weights per neuron, serving as consensus threshold for weight clipping | +| **Incentive** / `I` | Normalized ranks representing [incentive](../resources/glossary.md#incentives) allocation for miners based on performance | +| **Emission** / `E` | Token [emission](../resources/glossary.md#emission) amounts in [RAO](../resources/glossary.md#rao) (10^-9 TAO) per block | +| **Dividends** / `D` | [Bond](../resources/glossary.md#validator-miner-bonds)-based rewards for validators from their investments in miners | +| **Bonds** / `B` | Inter-neuronal [bond matrix](../resources/glossary.md#validator-miner-bonds) representing validator investments in miners, used to calculate validator emissions | +| **Weights** / `W` | [Weight matrix](../resources/glossary.md#weight-matrix) (validator → miner assignments) formed from validator weight vectors, input for [Yuma Consensus](../resources/glossary.md#yuma-consensus) | +| `uids` | Unique [UID](../resources/glossary.md#uid-slot) identifiers for each neuron | +| `hotkeys` | Neuron [hotkey](../resources/glossary.md#hotkey) addresses | +| `coldkeys` | Neuron [coldkey](../resources/glossary.md#coldkey) addresses | +| `addresses` | Network IP addresses | +| `axons` | Network connection details for [axon](../resources/glossary.md#axon) servers | +| `neurons` | Complete [neuron](../resources/glossary.md#neuron) objects with all metadata | +| `active` | Neuron activity status within the [`activity_cutoff`](./subnet-hyperparameters.md#activitycutoff) window | +| `last_update` | Last update block numbers for staleness detection | +| `validator_permit` | Boolean array indicating whether each neuron has [validator permits](../resources/glossary.md#validator-permit) to set weights and participate in consensus | +| `name` | Subnet name | +| `symbol` | Subnet token symbol | +| `network_registered_at` | Registration block when subnet was created | +| `num_uids` | Current number of neurons | +| `max_uids` | Maximum allowed neurons (typically 256) | +| `identities` | List of chain identities | +| `identity` | Subnet identity information | +| `pruning_score` | List of pruning scores based on emissions, used for [deregistration](../resources/glossary.md#deregistration) when subnet is full | +| `block_at_registration` | List of registration blocks for each neuron, used for [immunity period](../resources/glossary.md#immunity-period) calculations | +| `tao_dividends_per_hotkey` | [TAO](../resources/glossary.md#tao-tau) dividends by hotkey | +| `alpha_dividends_per_hotkey` | Alpha dividends by hotkey | +| `last_step` | Last step block number | +| `tempo` | [Tempo](../resources/glossary.md#tempo) - block interval for updates (360 blocks = 72 minutes) | +| `blocks_since_last_step` | Blocks since last step | +| `owner_coldkey` | Subnet owner [coldkey](../resources/glossary.md#coldkey) | +| `owner_hotkey` | Subnet owner [hotkey](../resources/glossary.md#hotkey) | +| `hparams` | Subnet [hyperparameters](./subnet-hyperparameters.md) (`MetagraphInfoParams`) | +| `pool` | Liquidity pool information (`MetagraphInfoPool`) | +| `emissions` | Emission configuration (`MetagraphInfoEmissions`) | +
+ +### Neuron Info + +A neuron represents any registered participant on the subnet, whether a miner or a validator. + +See also: + +- [Understanding Neurons](../learn/neurons.md) +- [NeuronInfo class specification, SDK reference](pathname:///python-api/html/autoapi/bittensor/core/chain_data/neuron_info/index.html#bittensor.core.chain_data.neuron_info.NeuronInfo) + +
+ Neuron Info Properties +| Name | Description | +--|-- +`uid` | Unique [UID](../resources/glossary.md#uid-slot) identifier for the neuron within the subnet +`hotkey` | [Hotkey](../resources/glossary.md#hotkey) address for network operations and signing +`coldkey` | [Coldkey](../resources/glossary.md#coldkey) address for secure storage and high-risk operations +`stake` | Total [stake weight](../resources/glossary.md#stake-weight) (α + τ × 0.18) determining consensus power and emissions +`rank` | Final [performance rank](../resources/glossary.md#rank) after consensus weight clipping, directly determining emissions +`trust` | [Consensus alignment](../resources/glossary.md#trust) ratio (final rank / pre-rank) measuring impact of consensus filtering +`consensus` | [Consensus score](../resources/glossary.md#consensus-score) - stake-weighted median of weights serving as clipping threshold +`incentive` | Normalized [incentive](../resources/glossary.md#incentives) score representing reward allocation for miners +`emission` | Token [emission](../resources/glossary.md#emission) rate in [RAO](../resources/glossary.md#rao) per block +`dividends` | [Bond](../resources/glossary.md#validator-miner-bonds)-based dividend amount for validators +`validator_trust` | [Validator trust](../resources/glossary.md#validator-trust) measuring validator influence in consensus +`active` | Activity status within the [`activity_cutoff`](./subnet-hyperparameters.md#activitycutoff) window +`last_update` | Last update block number for staleness detection +`validator_permit` | Boolean indicating [validator permit](../resources/glossary.md#validator-permit) status for weight setting and consensus participation +`weights` | [Weight vector](../resources/glossary.md#weight-vector) assignments from this neuron to others +`bonds` | [Bond](../resources/glossary.md#validator-miner-bonds) investments from this neuron to others +`axon_info` | Network connection details for the [axon](../resources/glossary.md#axon) server +
+ +### Axons + +An axon represents a server run by a registered miner, capable of answering requests by validators. + +See also: + +- [Understanding Neurons](../learn/neurons.md) +- [Axon class specification, SDK reference](pathname:///python-api/html/autoapi/bittensor/core/axon/index.html#module-bittensor.core.axon) +- [Axon class specification, SDK reference](pathname:///python-api/html/autoapi/bittensor/core/axon/index.html#module-bittensor.core.axon) + +
+ Axon Properties + +| Name | Description | +| -------------- | --------------------------------------------------------------- | +| `hotkey` | Neuron [hotkey](../resources/glossary.md#hotkey) address | +| `coldkey` | Neuron [coldkey](../resources/glossary.md#coldkey) address | +| `ip` | IP address for the [axon](../resources/glossary.md#axon) server | +| `port` | Port number for the axon server | +| `ip_type` | IP type (IPv4/IPv6) | +| `version` | Protocol version for axon-dendrite communication | +| `placeholder1` | Reserved field for future use | +| `placeholder2` | Reserved field for future use | + +
+ +### MetagraphInfoParams + +Represents the hyperparameters of a subnet. + +See also: + +- [Subnet Hyperparameters](./subnet-hyperparameters) +- [MetagraphInfoParams class specification, SDK reference](pathname:///python-api/html/autoapi/bittensor/core/chain_data/metagraph_info/index.html#bittensor.core.chain_data.metagraph_info.MetagraphInfoParams) + +
+ MetagraphInfoParams (Hyperparams) Properties + +| Name | Description | +| ------------------------------- | ---------------------------------------------------------------------------------------------- | +| `activity_cutoff` | Activity cutoff threshold | +| `adjustment_alpha` | Adjustment alpha parameter | +| `adjustment_interval` | Adjustment interval | +| `alpha_high` | Alpha high threshold | +| `alpha_low` | Alpha low threshold | +| `bonds_moving_avg` | Bonds moving average | +| `burn` | Burn amount | +| `commit_reveal_period` | Commit reveal period | +| `commit_reveal_weights_enabled` | Commit reveal weights enabled | +| `difficulty` | Network difficulty | +| `immunity_period` | Immunity period | +| `kappa` | Kappa parameter | +| `liquid_alpha_enabled` | Liquid alpha enabled | +| `max_burn` | Maximum burn | +| `max_difficulty` | Maximum difficulty | +| `max_regs_per_block` | Max registrations per block | +| `max_validators` | Maximum validators | +| `max_weights_limit` | Maximum weights limit | +| `min_allowed_weights` | Minimum allowed weights | +| `min_burn` | Minimum burn | +| `min_difficulty` | Minimum difficulty | +| `pow_registration_allowed` | POW registration allowed | +| `registration_allowed` | Registration allowed | +| `rho` | Rho parameter | +| `serving_rate_limit` | Serving rate limit | +| `target_regs_per_interval` | Target registrations per interval | +| `tempo` | [Tempo](../resources/glossary.md#tempo) - block interval for updates (360 blocks = 72 minutes) | +| `weights_rate_limit` | [Weights](../resources/glossary.md#weight-vector) rate limit for submissions | +| `weights_version` | [Weights](../resources/glossary.md#weight-vector) version for protocol compatibility | + +
+ +### MetagraphInfoPool + +Contains information about the subnet's liquidity pool + +See also: + +- [Understanding Subnets: Liquidity pools](./understanding-subnets#liquidity-pools). +- [MetagraphInfoPool class specification, SDK reference](pathname:///python-api/html/autoapi/bittensor/core/chain_data/metagraph_info/index.html#bittensor.core.chain_data.metagraph_info.MetagraphInfoPool) + +
+ MetagraphInfoPool properties +| Name | Description | +--|-- +`alpha_out` | Alpha token quanitity bound for emission to subnet participants +`alpha_in` | Alpha token quanitity emitted to the liquidity pool +`tao_in` | Tao token emission to the liquidity pool +`subnet_volume` | Total trading volume in the subnet's liquidity pool +`moving_price` | Moving average price of the subnet token +
+ +### MetagraphInfoEmissions + +Contains detailed information about the subnet's emissions. + +See also: + +- [Emissions](../learn/emissions). +- [MetagraphInfoEmissions class specification, SDK reference](pathname:///python-api/html/autoapi/bittensor/core/chain_data/metagraph_info/index.html#bittensor.core.chain_data.metagraph_info.MetagraphInfoPool) + +
+ MetagraphInfoEmissions properties +| Name | Description | +--|-- +`alpha_out_emission` | Alpha token outflow [emission](../resources/glossary.md#emission) rate +`alpha_in_emission` | Alpha token inflow [emission](../resources/glossary.md#emission) rate +`subnet_emission` | Subnet [emission](../resources/glossary.md#emission) rate to participants +`tao_in_emission` | [TAO](../resources/glossary.md#tao-tau) token inflow [emission](../resources/glossary.md#emission) rate +`pending_alpha_emission` | Pending alpha token [emission](../resources/glossary.md#emission) amount +`pending_root_emission` | Pending root network [emission](../resources/glossary.md#emission) amount +
+ +## Python Code Examples + +This section provides practical examples of working with the Bittensor metagraph using the Python SDK. Each example demonstrates different aspects of metagraph analysis and data extraction. + + +**Prerequisites**: + +- Bittensor Python SDK installed (`pip install bittensor`) +- Network connection to access Bittensor blockchain +- Python 3.7+ environment + +### Basic Metagraph Information + +This example shows how to access basic metagraph metadata and subnet information: + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get basic metagraph metadata + print("\n=== Basic Metagraph Metadata ===") + print(f"Network: {metagraph.network}") + print(f"Subnet UID: {metagraph.netuid}") + print(f"Total neurons: {metagraph.n.item()}") + print(f"Current block: {metagraph.block.item()}") + print(f"Version: {metagraph.version.item()}") + + # Get subnet information + print("\n=== Subnet Information ===") + print(f"Subnet name: {metagraph.name}") + print(f"Subnet symbol: {metagraph.symbol}") + print(f"Registered at block: {metagraph.network_registered_at}") + print(f"Max UIDs: {metagraph.max_uids}") + print(f"Owner: {metagraph.owner_coldkey}") + +if __name__ == "__main__": + main() +``` + +### Neuron Metrics Analysis + +This example demonstrates stake distribution and neuron metrics analysis: + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get all neuron UIDs + uids = metagraph.uids + print(f"\nNeuron UIDs: {uids.tolist()}") + + # Analyze stake distribution + stakes = metagraph.S # Total stake + alpha_stakes = metagraph.AS # Alpha token stake + tao_stakes = metagraph.TS # TAO token stake + + print(f"\n=== Stake Analysis ===") + print(f"Total stake across all neurons: {stakes.sum().item():.2f}") + print(f"Average stake per neuron: {stakes.mean().item():.2f}") + print(f"Highest stake: {stakes.max().item():.2f}") + print(f"Lowest stake: {stakes.min().item():.2f}") + + # Find top staked neurons + top_staked_indices = stakes.argsort()[::-1][:10] + print("\nTop 10 staked neurons:") + for i, idx in enumerate(top_staked_indices): + uid = uids[idx].item() + stake = stakes[idx].item() + print(f" {i+1}. UID {uid}: {stake:.2f} τ") + +if __name__ == "__main__": + main() +``` + +### Performance and Ranking Analysis + +This example shows how to analyze neuron performance, ranks, and trust scores: + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get performance metrics + ranks = metagraph.R # Performance ranks + trust = metagraph.T # Trust scores + consensus = metagraph.C # Consensus scores + validator_trust = metagraph.Tv # Validator trust + uids = metagraph.uids + + # Find top performing neurons + top_ranked_indices = ranks.argsort()[::-1][:10] + print("\n=== Top 10 Ranked Neurons ===") + for i, idx in enumerate(top_ranked_indices): + uid = uids[idx].item() + rank = ranks[idx].item() + trust_score = trust[idx].item() + consensus_score = consensus[idx].item() + print(f" {i+1}. UID {uid}: Rank={rank:.4f}, Trust={trust_score:.4f}, Consensus={consensus_score:.4f}") + + # Analyze trust distribution + print(f"\n=== Trust Analysis ===") + print(f"Average trust score: {trust.mean().item():.4f}") + print(f"Trust score std dev: {trust.std().item():.4f}") + print(f"Highest trust: {trust.max().item():.4f}") + print(f"Lowest trust: {trust.min().item():.4f}") + + # Find most trusted validators + validator_indices = metagraph.validator_permit.nonzero()[0] + if len(validator_indices) > 0: + validator_trust_scores = validator_trust[validator_indices] + top_validators = validator_indices[validator_trust_scores.argsort()[::-1][:5]] + print("\n=== Top 5 Trusted Validators ===") + for i, idx in enumerate(top_validators): + uid = uids[idx].item() + vtrust = validator_trust[idx].item() + print(f" {i+1}. UID {uid}: Validator Trust={vtrust:.4f}") + else: + print("\nNo validators found in this subnet.") + +if __name__ == "__main__": + main() +``` + +### Economic Analysis + +This example demonstrates analysis of economic metrics like incentives, emissions, and dividends: + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get economic metrics + incentives = metagraph.I # Incentive scores + emissions = metagraph.E # Emission rates + dividends = metagraph.D # Dividend distributions + uids = metagraph.uids + + # Analyze incentive distribution + print(f"\n=== Incentive Analysis ===") + print(f"Total incentives: {incentives.sum().item():.4f}") + print(f"Average incentive: {incentives.mean().item():.4f}") + print(f"Highest incentive: {incentives.max().item():.4f}") + + # Find highest incentivized neurons + top_incentive_indices = incentives.argsort()[::-1][:10] + print("\n=== Top 10 Incentivized Neurons ===") + for i, idx in enumerate(top_incentive_indices): + uid = uids[idx].item() + incentive = incentives[idx].item() + emission = emissions[idx].item() + dividend = dividends[idx].item() + print(f" {i+1}. UID {uid}: Incentive={incentive:.4f}, Emission={emission:.4f}, Dividend={dividend:.4f}") + + # Analyze dividend distribution + print(f"\n=== Dividend Analysis ===") + print(f"Total dividends: {dividends.sum().item():.4f}") + print(f"Average dividend: {dividends.mean().item():.4f}") + print(f"Dividend std dev: {dividends.std().item():.4f}") + +if __name__ == "__main__": + main() +``` + +### Network Connectivity Analysis + +This example shows how to analyze network addresses and axon information: + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get network information + axons = metagraph.axons + uids = metagraph.uids + + # Analyze network addresses + addresses = [axon.ip for axon in axons] + unique_addresses = set(addresses) + unique_hotkeys = set(metagraph.hotkeys) + unique_coldkeys = set(metagraph.coldkeys) + + print(f"\n=== Network Address Analysis ===") + print(f"Total unique addresses: {len(unique_addresses)}") + print(f"Total unique hotkeys: {len(unique_hotkeys)}") + print(f"Total unique coldkeys: {len(unique_coldkeys)}") + + # Find neurons sharing addresses + address_to_uids = {} + for i, address in enumerate(addresses): + if address not in address_to_uids: + address_to_uids[address] = [] + address_to_uids[address].append(uids[i].item()) + + print(f"\n=== Neurons Sharing Addresses ===") + for address, uids_list in address_to_uids.items(): + if len(uids_list) > 1: + print(f" Address {address}: UIDs {uids_list}") + + # Show axon details for first few neurons + print(f"\n=== Axon Details (First 5 Neurons) ===") + for i in range(min(5, len(axons))): + axon = axons[i] + uid = uids[i].item() + hotkey = metagraph.hotkeys[i][:10] + "..." + print(f" UID {uid}: IP={axon.ip}, Port={axon.port}, Hotkey={hotkey}") + +if __name__ == "__main__": + main() +``` + +### Weight Matrix Analysis + +This example demonstrates weight matrix analysis (requires `lite=False`): + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 with full sync (not lite) + print("Initializing metagraph for subnet 1 (full sync)...") + metagraph = Metagraph(netuid=1, network="finney", lite=False, sync=True) + + uids = metagraph.uids + + # Get weight matrix (requires lite=False) + if not metagraph.lite and hasattr(metagraph, 'weights') and metagraph.weights.size > 0: + weights = metagraph.W # Weight matrix + + print(f"\n=== Weight Matrix Analysis ===") + print(f"Weight matrix shape: {weights.shape}") + print(f"Total weights: {weights.sum().item():.4f}") + print(f"Average weight: {weights.mean().item():.4f}") + print(f"Max weight: {weights.max().item():.4f}") + + # Find miners receiving most weights + weight_received = weights.sum(axis=0) # Sum of incoming weights + top_receivers = weight_received.argsort()[::-1][:10] + print("\n=== Miners Receiving Most Frequent Weights ===") + for i, idx in enumerate(top_receivers): + uid = uids[idx].item() + total_weight = weight_received[idx].item() + print(f" {i+1}. UID {uid}: {total_weight:.4f}") + + # Find validators sending most weights + weight_sent = weights.sum(axis=1) # Sum of outgoing weights + top_senders = weight_sent.argsort()[::-1][:10] + print("\n=== Validators Setting Weights Most Frequently ===") + for i, idx in enumerate(top_senders): + uid = uids[idx].item() + total_weight = weight_sent[idx].item() + print(f" {i+1}. UID {uid}: {total_weight:.4f}") + + # Find highest set weight + max_weight_idx = weights.argmax() + sender_idx = max_weight_idx // weights.shape[1] + receiver_idx = max_weight_idx % weights.shape[1] + max_weight = weights.max().item() + print(f"\n=== Highest Single Set Weight ===") + print(f"UID {uids[sender_idx].item()} -> UID {uids[receiver_idx].item()}: {max_weight:.4f}") + else: + print("Weights not available. Make sure to use lite=False when initializing the metagraph.") + +if __name__ == "__main__": + main() +``` + +### Bond Analysis + +This example shows bond matrix analysis (requires `lite=False`): + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 with full sync (not lite) + print("Initializing metagraph for subnet 1 (full sync)...") + metagraph = Metagraph(netuid=1, network="finney", lite=False, sync=True) + + uids = metagraph.uids + + # Get bond matrix (requires lite=False) + if not metagraph.lite and hasattr(metagraph, 'bonds') and metagraph.bonds.size > 0: + bonds = metagraph.B # Bond matrix + + print(f"\n=== Bond Matrix Analysis ===") + print(f"Bond matrix shape: {bonds.shape}") + print(f"Total bonds: {bonds.sum().item():.4f}") + print(f"Average bond: {bonds.mean().item():.4f}") + + # Find miners with most bonds + bonds_received = bonds.sum(axis=0) # Sum of incoming bonds + top_bonded = bonds_received.argsort()[::-1][:10] + print("\n=== Top 10 Most Bonded Miners ===") + for i, idx in enumerate(top_bonded): + uid = uids[idx].item() + total_bonds = bonds_received[idx].item() + print(f" {i+1}. UID {uid}: {total_bonds:.4f}") + else: + print("Bonds not available. Make sure to use lite=False when initializing the metagraph.") + +if __name__ == "__main__": + main() +``` + +### Neuron Activity Analysis + +This example demonstrates analyzing validator activity: + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get activity information + active = metagraph.active # Activity status + last_update = metagraph.last_update # Last update blocks + validator_permit = metagraph.validator_permit # Validator permissions + uids = metagraph.uids + stakes = metagraph.S + ranks = metagraph.R + + # Analyze activity + active_count = active.sum().item() + total_count = len(active) + print(f"\n=== Activity Analysis ===") + print(f"Active validators: {active_count}/{total_count} ({active_count/total_count:.1%})") + + + # Analyze validator distribution + validator_count = validator_permit.sum().item() + print(f"\n=== Validator Analysis ===") + print(f"Validators: {validator_count}/{total_count} ({validator_count/total_count:.1%})") + + # Find validators + validator_indices = validator_permit.nonzero()[0] + if len(validator_indices) > 0: + print("\n=== Validators ===") + for idx in validator_indices: + uid = uids[idx].item() + stake = stakes[idx].item() + rank = ranks[idx].item() + print(f" UID {uid}: Stake={stake:.2f}, Rank={rank:.4f}") + else: + print("\nNo validators found in this subnet.") + +if __name__ == "__main__": + main() +``` + +### Subnet Economics + +This example shows how to access subnet hyperparameters, pool, and emissions: + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get subnet hyperparameters + hparams = metagraph.hparams + print(f"\n=== Subnet Hyperparameters ===") + print(f" Activity cutoff: {hparams.activity_cutoff}") + print(f" Adjustment alpha: {hparams.adjustment_alpha}") + print(f" Adjustment interval: {hparams.adjustment_interval}") + print(f" Alpha high: {hparams.alpha_high}") + print(f" Alpha low: {hparams.alpha_low}") + print(f" Burn rate: {hparams.burn_rate}") + print(f" Max burn: {hparams.max_burn}") + print(f" Min burn: {hparams.min_burn}") + print(f" Difficulty: {hparams.difficulty}") + print(f" Max difficulty: {hparams.max_difficulty}") + print(f" Min difficulty: {hparams.min_difficulty}") + print(f" Max validators: {hparams.max_validators}") + print(f" Tempo: {hparams.tempo}") + print(f" Weights version: {hparams.weights_version}") + + # Get subnet pool information + pool = metagraph.pool + print(f"\n=== Subnet Pool ===") + print(f" Alpha out: {pool.alpha_out}") + print(f" Alpha in: {pool.alpha_in}") + print(f" TAO in: {pool.tao_in}") + print(f" Subnet volume: {pool.subnet_volume}") + print(f" Moving price: {pool.moving_price}") + + # Get subnet emissions + emissions = metagraph.emissions + print(f"\n=== Subnet Emissions ===") + print(f" Alpha out emission: {emissions.alpha_out_emission}") + print(f" Alpha in emission: {emissions.alpha_in_emission}") + print(f" Subnet emission: {emissions.subnet_emission}") + print(f" TAO in emission: {emissions.tao_in_emission}") + print(f" Pending alpha emission: {emissions.pending_alpha_emission}") + print(f" Pending root emission: {emissions.pending_root_emission}") + +if __name__ == "__main__": + main() +``` + +### Advanced Analysis Examples + +This example demonstrates advanced analysis techniques including correlations and [Gini coefficient](https://en.wikipedia.org/wiki/Gini_coefficient) of stake distribution. + +```python +#!/usr/bin/env python3 + +import numpy as np +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get basic metrics + stakes = metagraph.S + ranks = metagraph.R + trust = metagraph.T + uids = metagraph.uids + + # Correlation analysis between metrics + print("\n=== Metric Correlations ===") + try: + # Calculate correlations + stake_rank_corr = np.corrcoef(stakes, ranks)[0, 1] + stake_trust_corr = np.corrcoef(stakes, trust)[0, 1] + rank_trust_corr = np.corrcoef(ranks, trust)[0, 1] + + print("Metric Correlations:") + print(f" Stake vs Rank: {stake_rank_corr:.4f}") + print(f" Stake vs Trust: {stake_trust_corr:.4f}") + print(f" Rank vs Trust: {rank_trust_corr:.4f}") + except Exception as e: + print(f"Could not calculate correlations: {e}") + + # Network efficiency analysis (if weights are available) + if not metagraph.lite and hasattr(metagraph, 'weights') and metagraph.weights.size > 0: + weights = metagraph.W + + print("\n=== Network Efficiency Analysis ===") + # Calculate network efficiency (average path length) + non_zero_weights = weights[weights > 0] + if len(non_zero_weights) > 0: + avg_weight = non_zero_weights.mean().item() + weight_std = non_zero_weights.std().item() + print(f"Network efficiency:") + print(f" Average non-zero weight: {avg_weight:.4f}") + print(f" Weight standard deviation: {weight_std:.4f}") + print(f" Weight distribution CV: {weight_std/avg_weight:.4f}") + else: + print("\nWeights not available for network efficiency analysis.") + + # Stake concentration analysis + print("\n=== Stake Concentration Analysis ===") + total_stake = stakes.sum().item() + try: + stake_percentiles = np.percentile(stakes, [25, 50, 75, 90, 95, 99]) + print("Stake distribution percentiles:") + for p, val in zip([25, 50, 75, 90, 95, 99], stake_percentiles): + print(f" {p}th percentile: {val:.2f} τ") + + # Gini coefficient for stake inequality + sorted_stakes = np.sort(stakes) + n = len(sorted_stakes) + cumulative_stakes = np.cumsum(sorted_stakes) + gini = (n + 1 - 2 * np.sum(cumulative_stakes) / cumulative_stakes[-1]) / n + print(f"Stake Gini coefficient: {gini:.4f}") + except Exception as e: + print(f"Could not calculate stake concentration metrics: {e}") + +if __name__ == "__main__": + main() +``` + +### Async Usage + +This example demonstrates async metagraph usage: + +```python +#!/usr/bin/env python3 + +import asyncio +from bittensor.core.metagraph import async_metagraph + +async def analyze_metagraph(): + # Create async metagraph + print("Creating async metagraph...") + metagraph = await async_metagraph(netuid=1, network="finney", lite=False) + + # Perform analysis + stakes = metagraph.S + print(f"Total stake: {stakes.sum().item():.2f}") + + # Sync to latest block + print("Syncing to latest block...") + await metagraph.sync() + print(f"Synced to block: {metagraph.block.item()}") + +async def main(): + print("=== Async Metagraph Analysis ===") + await analyze_metagraph() + +if __name__ == "__main__": + # Run async analysis + asyncio.run(main()) +``` + +### Complete Neuron Information + +This example shows how to access complete neuron object information: + +```python +#!/usr/bin/env python3 + +from bittensor.core.metagraph import Metagraph + +def main(): + # Initialize metagraph for subnet 1 + print("Initializing metagraph for subnet 1...") + metagraph = Metagraph(netuid=1, network="finney", sync=True) + + # Get complete neuron information for first 5 neurons + print("=== Complete Neuron Information (First 5 Neurons) ===") + + for i in range(min(5, metagraph.n.item())): + neuron = metagraph.neurons[i] + print(f"\nNeuron {i}:") + print(f" UID: {neuron.uid}") + print(f" Hotkey: {neuron.hotkey}") + print(f" Coldkey: {neuron.coldkey}") + print(f" Stake: τ{neuron.stake:.9f}") + print(f" Rank: {neuron.rank}") + print(f" Trust: {neuron.trust}") + print(f" Consensus: {neuron.consensus}") + print(f" Incentive: {neuron.incentive}") + print(f" Emission: {neuron.emission}") + print(f" Dividends: {neuron.dividends}") + print(f" Active: {neuron.active}") + print(f" Last update: {neuron.last_update}") + print(f" Validator permit: {neuron.validator_permit}") + print(f" Validator trust: {neuron.validator_trust}") + print(f" Axon IP: {neuron.axon.ip}") + print(f" Axon port: {neuron.axon.port}") + print(f" ---") + +if __name__ == "__main__": + main() +``` + +## Source Code References + +### Core Implementation + +- **Metagraph Class**: [`bittensor/bittensor/core/metagraph.py`](https://github.com/opentensor/bittensor/blob/main/bittensor/core/metagraph.py) +- **Chain Data**: [`bittensor/bittensor/core/chain_data/metagraph_info.py`](https://github.com/opentensor/bittensor/blob/main/bittensor/core/chain_data/metagraph_info.py) +- **Subtensor RPC**: [`subtensor/pallets/subtensor/src/rpc_info/metagraph.rs`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/rpc_info/metagraph.rs) + +### Consensus Algorithm + +- **Yuma Consensus**: [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs) +- **Mathematical Operations**: [`subtensor/pallets/subtensor/src/epoch/math.rs`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/math.rs) + +### Key Constants + +- **TAO Stake Weight**: [`bittensor/bittensor/core/settings.py:7`](https://github.com/opentensor/bittensor/blob/main/bittensor/core/settings.py#L7) - `ROOT_TAO_STAKE_WEIGHT = 0.18` diff --git a/docs/subnets/subnet-creators-btcli-guide.md b/docs/subnets/subnet-creators-btcli-guide.md index 4a796cd44d..cab7f0bc64 100644 --- a/docs/subnets/subnet-creators-btcli-guide.md +++ b/docs/subnets/subnet-creators-btcli-guide.md @@ -4,23 +4,26 @@ title: "Subnet Creator's Guide to `BTCLI`" # Subnet Creator's Guide to `BTCLI` -Subnet creators define and manage new subnets, specifying parameters like burn cost, hyperparameters, or other chain-level configurations. This role inherently requires a **coldkey** with sufficient balance/permissions to create or update subnets. +Subnet creators define and manage new subnets, specifying parameters like burn cost, hyperparameters, or other chain-level configurations. This role inherently requires a **coldkey** with sufficient balance/permissions to create or update subnets. -This page discusses btcli stuff specifically for Subnet Creators. For general coverage of BTCLI and permissions stuff, see: [Bittensor CLI: Permissions Guide](../btcli-permissions) +This page discusses btcli stuff specifically for Subnet Creators. For general coverage of BTCLI and permissions stuff, see: [Bittensor CLI: Permissions Guide](../btcli/btcli-permissions) -See also: [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security). +See also: [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security). ## Subnet Creator Requirements -To create a new subnet, you need a coldkey with sufficient TAO to pay the burn cost for creating a subnet +To create a new subnet, you need a coldkey with sufficient TAO to pay the burn cost for creating a subnet To modify a subnet, you need the coldkey associated with ownership of the subnet ## `btcli` commands for subnet creators + ### monitor subnet + Permissionless, use `btcli subnet show` or `btcli view dashboard`. ### create subnet + Requires coldkey with sufficient TAO. `btcli subnet create` @@ -32,5 +35,4 @@ Configure your subnet's hyperparameters with `btcli sudo set`. Requires the cold If you suspect your coldkey may have been leaked, you can request to swap it out of your wallet, using an extrinsic blockchain transaction. This operation has a 5 day waiting period, during which your coldkey will be locked. The cost of this coldkey swap transaction is 0.1 TAO. -See [Rotate/Swap your Coldkey](../subnets/schedule-coldkey-swap) - +See [Rotate/Swap your Coldkey](../keys/schedule-coldkey-swap) diff --git a/docs/subnets/subnet-deregistration.md b/docs/subnets/subnet-deregistration.md new file mode 100644 index 0000000000..6702164e42 --- /dev/null +++ b/docs/subnets/subnet-deregistration.md @@ -0,0 +1,115 @@ +--- +title: "Subnet Deregistration" +--- + +# Subnet Deregistration + +This page details the process by which subnets can become deregistered from Bittensor network, with an eye to the implementation of the functionality in the Subtensor codebase that makes up Bittensor's blockchain layer. + +See also [Learn Bittensor: Subnet Deregistration](https://learnbittensor.org/concepts/dynamic-tao/subnet-deregistration) + +Subnet deregistration is a mechanism that manages the lifecycle of subnets within the Bittensor network. It ensures network quality by removing underperforming subnets, clearing room for new subnet registrations within the 128 subnet limit. + +:::info Deployment Timeline +The subnet deregistration feature deployed on September 17, 2025, with a 7-day delay before the first registrations can occur. +::: + +Subnet deregistration addresses network efficiency issues: +- Removes underperforming subnets that consume TAO emissions without providing value. +- Unlocks TAO resources locked in underperforming subnet pools + +| Parameter | Value | Description | +|-----------|-------|-------------| +| **Subnet Limit** | 128 | Maximum number of occupied subnet slots | +| **Immunity Period** | 4 months (864000 blocks) | Protection period from subnet deregistration +| **Rate Limiting** | 4 days (28800 blocks) | Minimum time between registrations/deregistrations | + +## The Automated Deregistration Process + +### Trigger + +The process begins when the subnet limit is reached and a new subnet attempts to register. + +Source: [`do_register_network()`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/subnet.rs#L146-158) + +### Selection Criteria +The subnet to deregister is the subnet with lowest EMA (Exponential Moving Average) price among non-immune subnets. + +Source code: [`get_network_to_prune()`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/coinbase/root.rs#L753-795) + +The subnet price EMA uses the standard EMA formula: +$$ +\mathrm{EMA}^{(t)} = \alpha \times \mathrm{current\_price} + (1 - \alpha) \times \mathrm{EMA}^{(t-1)} +$$ + +Where $\alpha$ is calculated dynamically based on subnet age: +$$ +\alpha = \frac{\mathrm{base\_alpha} \times \mathrm{blocks\_since\_start}}{\mathrm{blocks\_since\_start} + \mathrm{halving\_blocks}} +$$ + +- **base_alpha**: ~0.0003 for Bittensor mainnet ("finney") +- **blocks_since_start**: Number of blocks since subnet registration +- **halving_blocks**: Halving period for the subnet + +This EMA value is recalculated for the subnet each time the coinbase function runs. + +See also: +- [Navigating Subtensor Codebase: Coinbase Implementation](../navigating-subtensor/emissions-coinbase) +- [Exponential Moving Averages (EMAs) in Bittensor](../learn/ema.md). + + +### Immunity Protection +Network immunity period is currently 4 months from registration block. + - Formula: `current_block < registered_at + network_immunity_period` + - Source code: [Immunity check](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/coinbase/root.rs#L768-770) +### Rate Limiting +Deregistration can occur at most every once every 4 days (coordinated with registration rate). + - Block-based timing: 28800 blocks ≈ 4 days at 12s/block + - [Source code](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/utils/rate_limiting.rs#L27) + +See [Rate Limits in Bittensor](../learn/chain-rate-limits.md). + +## Special Cases and Edge Conditions + +### All Subnets Immune +If all subnets are still within their immunity period, the system will: +1. Return `None` from [`get_network_to_prune()`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/coinbase/root.rs#L753-795) +2. Registration fails with `SubnetLimitReached` error +3. No subnet is deregistered until at least one becomes eligible + +### Tied EMA Prices + +When multiple subnets have identical EMA prices: +1. Select the subnet with the earliest registration timestamp +2. Implementation: [Tie-breaking logic](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/coinbase/root.rs#L774-781) + +## Token Liquidation + +When a subnet is deregistered, all alpha tokens in that subnet are liquidated and the subnet's TAO pool is distributed to alpha holders and to refunding the subnet owner for their lock cost minus the emissions they've received. + +### Takeaways + +**Distribution Method**: Largest-remainder for fair rounding +**Owner Protection**: Owner gets refund minus emissions already received +**Immediate Effect**: All alpha tokens are destroyed and cannot be recovered + +### Liquidation Steps + +1. **Dissolve Liquidity Pools**: All liquidity pools in the subnet's AMM pools are dissolved +2. **Calculate Owner Refund**: The subnet owner's refund is calculated as: + ``` + refund = max(0, lock_cost - owner_received_emission_in_tao) + ``` + Where `owner_received_emission_in_tao` is the TAO value of the owner's cut of all emissions received during the subnet's lifetime. + +3. **Enumerate alpha Holders**: All alpha token holders and their stake amounts are collected + +4. **Extract TAO Pool**: The subnet's TAO pool (`SubnetTAO`) is extracted for distribution + +5. **Distribution**: TAO is distributed proportionally to alpha holders: + - Each holder receives: `(holder_alpha_value / total_alpha_value) * pool_tao` + - TAO is credited directly to each holder's coldkey free balance + +**Source Code**: +- [`destroy_alpha_in_out_stakes()`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/staking/remove_stake.rs#L444-623) +- [`prune_network()`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/coinbase/root.rs#L377) diff --git a/docs/subnets/subnet-hyperparameters.md b/docs/subnets/subnet-hyperparameters.md index ef1b8bbc99..770d193e35 100644 --- a/docs/subnets/subnet-hyperparameters.md +++ b/docs/subnets/subnet-hyperparameters.md @@ -34,35 +34,41 @@ Using the specified network test from config HYPERPARAMETER VALUE NORMALIZED ──────────────────────────────────────────────────────────────────────── - rho 10 10 - kappa 32767 0.4999923705 - immunity_period 5000 5000 - min_allowed_weights 1 1 - max_weights_limit 65535 65535 - tempo 99 99 - min_difficulty 10000000 5.421010862e-13 - max_difficulty 18446744073709551615 1 - weights_version 0 0 - weights_rate_limit 100 100 - adjustment_interval 360 360 activity_cutoff 5000 5000 - registration_allowed True True - target_regs_per_interval 1 1 - min_burn 500000 τ 0.0005 - max_burn 100000000000 τ 100.0000 + adjustment_alpha 17893341751498265066 0.97 + adjustment_interval 360 360 + alpha_high 58982 0.9000076295 + alpha_low 45875 0.7000076295 + alpha_sigmoid_steepness 0.0 0 bonds_moving_avg 900000 4.878909776e-14 - max_regs_per_block 1 1 - serving_rate_limit 50 50 - max_validators 64 64 - adjustment_alpha 58000 3.1441863e-15 - difficulty 10000000 5.421010862e-13 + bonds_reset_enabled False False commit_reveal_period 1 1 commit_reveal_weights_enabled False False - alpha_high 58982 0.9000076295 - alpha_low 45875 0.7000076295 + difficulty 18446744073709551615 1 + immunity_period 5000 5000 + kappa 32767 0.4999923705 liquid_alpha_enabled False False + max_burn 100000000000 100.0000 τ + max_difficulty 18446744073709551615 1 + max_regs_per_block 1 1 + max_validators 64 64 + max_weight_limit 65535 1 + min_allowed_weights 1 1 + min_burn 500000 0.0005 τ + min_difficulty 18446744073709551615 1 + registration_allowed True True + rho 10 10 + serving_rate_limit 50 50 + subnet_is_active True True + target_regs_per_interval 1 1 + tempo 360 360 + transfers_enabled True True + user_liquidity_enabled True True + weights_rate_limit 100 100 + weights_version 0 0 + yuma_version 2 2 ──────────────────────────────────────────────────────────────────────── - ``` +``` :::tip @@ -111,14 +117,13 @@ The number of blocks for the stake to become inactive for the purpose of epoch i **`btcli` setter**: `btcli sudo set --param adjustment_alpha` -**Setter extrinsic**: `sudo_set_activity_cutoff` +**Setter extrinsic**: `sudo_set_adjustment_alpha` **Permissions required to set**: Subnet Creator **Description**: `AdjustmentAlpha` is the rate at which difficulty and burn are adjusted up or down. - ### AdjustmentInterval **Type**: u16 @@ -133,18 +138,32 @@ The number of blocks for the stake to become inactive for the purpose of epoch i **Description**: -`AdjustmentInterval` is number of blocks that pass between difficulty and burn adjustments. So, I was wrong about "next block" when I said that if root sets difficulty outside of range, it will get back in range. Difficulty will get back in range at most after `AdjustmentInterval` blocks pass. +`AdjustmentInterval` is number of blocks that pass between difficulty and burn adjustments. + +### AlphaSigmoidSteepness + +**Type**: u16 + +**Default**: 1000 + +**`btcli` setter**: `btcli sudo set --param alpha_sigmoid_steepness` + +**Setter extrinsic**: `sudo_set_alpha_sigmoid_steepness` +**Permissions required to set**: Subnet Creator + +**Description**: +`AlphaSigmoidSteepness` determines how the consensus mechanism assigns an alpha value for a given miner-validator pair based on voting alignment. Lower steepness values result in moderate alpha values, while higher steepness values push alpha values closer to the defined `alpha_low` or `alpha_high` values. ### BondsMovingAverage -**Type**: +**Type**: -**Default**: +**Default**: -**`btcli` setter**: bonds_moving_avg +**`btcli` setter**: `btcli sudo set --param bonds_moving_avg` -**`btcli` setter**: `btcli sudo set --param sudo_set_bonds_moving_average` +**`btcli` setter**: `sudo_set_bonds_moving_average` **Permissions required to set**: Subnet Creator @@ -152,8 +171,7 @@ The number of blocks for the stake to become inactive for the purpose of epoch i The moving average of bonds. The higher bonds yield to higher dividends for validators. -See [Yuma Consensus: bonding mechanics](../yuma-consensus#bonding-mechanics). - +See [Yuma Consensus: bonding mechanics](../learn/yuma-consensus#bonding-mechanics). ### BondsPenalty @@ -166,18 +184,34 @@ See [Yuma Consensus: bonding mechanics](../yuma-consensus#bonding-mechanics). **Setter extrinsic**: `sudo_set_bonds_penalty` **Permissions required to set**: root + **Description**: The magnitude of the penalty subtracted from weights for exceeding consensus, for a specific subnet. -See [Yuma Consensus: Penalizing out-of-consensus bonds](../yuma-consensus#penalizing-out-of-consensus-bonds). +See [Yuma Consensus: Penalizing out-of-consensus bonds](../learn/yuma-consensus#penalizing-out-of-consensus-bonds). + +### BondsResetEnabled +**Type**: Bool + +**Default**: False + +**`btcli` setter**: `btcli sudo set --param bonds_reset_enabled` + +**Setter extrinsic**: `sudo_set_bonds_reset_enabled` + +**Permissions required to set**: Subnet creator + +**Description**: + +Determines whether or not bonds are reset-enabled. ### CommitRevealPeriod -**Type**: u16 - +**Type**: u16 + **Default**: 1 **`btcli` setter**: `btcli sudo set --param commit_reveal_period` @@ -188,9 +222,11 @@ See [Yuma Consensus: Penalizing out-of-consensus bonds](../yuma-consensus#penali **Description**: -How long, in blocks, the consensus weights for a subnet remain time-lock encrypted, preventing weight-copying. +The number of **tempos** (epochs) that must elapse before validator weights are revealed from time-lock encryption. Prevents weight-copying. + +**Important**: This is measured in **tempos** (not blocks, as you might expect). A tempo equals the subnet's `tempo` hyperparameter (typically 360 blocks). For example, if you set `commit_reveal_period` to 3 and your `tempo` is 360, weights will be revealed after 3 tempos = 1080 blocks. -See [Commit Reveal](./commit-reveal) +See [Commit Reveal](../concepts/commit-reveal) for details on how commit reveal works. ### CommitRevealWeightsEnabled @@ -198,7 +234,7 @@ See [Commit Reveal](./commit-reveal) **Default**: false -**`btcli` setter**: yes +**`btcli` setter**: `btcli sudo set --param commit_reveal_weights_enabled` **Setter extrinsic**: `sudo_set_commit_reveal_weights_enabled` @@ -206,8 +242,7 @@ See [Commit Reveal](./commit-reveal) **Description**: - Enables [Commit Reveal](./commit-reveal) - +Enables [Commit Reveal](../concepts/commit-reveal) ### Difficulty @@ -215,9 +250,9 @@ See [Commit Reveal](./commit-reveal) **Default**: 10000000 -**`btcli` setter**: none +**`btcli` setter**: `btcli sudo set --param difficulty` -**Setter extrinsic**: `sudo_set_difficulty` +**Setter extrinsic**: `sudo_set_difficulty` **Permissions required to set**: Root @@ -227,17 +262,15 @@ Current dynamically computed value for the proof-of-work (POW) requirement for P - ### ImmunityPeriod - **Type**: u16 **Default**: 5000 -**`btcli` setter**: yes +**`btcli` setter**: `btcli sudo set --param immunity_period` -**Setter extrinsic**: `sudo_set_immunity_period` +**Setter extrinsic**: `sudo_set_immunity_period` **Permissions required to set**: Subnet creator @@ -245,15 +278,13 @@ Current dynamically computed value for the proof-of-work (POW) requirement for P The number of blocks after registration when a miner is protected from deregistration - ### Kappa - **Type**: u16 -**Default**: 32767 ( or approximately 0.5 normalized ) +**Default**: 32767 ( or approximately 0.5 normalized ) -**`btcli` setter**: yes +**`btcli` setter**: `btcli sudo set --param kappa` **Setter extrinsic**: `sudo_set_kappa` @@ -263,9 +294,7 @@ The number of blocks after registration when a miner is protected from deregistr The consensus majority ratio: The weights set by validators who have lower normalized stake than Kappa are not used in calculating consensus, which affects ranks, which affect incentives. - - -the consensus threshold for bond-clipping during [Yuma Consensus](../yuma-consensus) +the consensus threshold for bond-clipping during [Yuma Consensus](../learn/yuma-consensus) ### LiquidAlphaEnabled @@ -281,14 +310,10 @@ the consensus threshold for bond-clipping during [Yuma Consensus](../yuma-consen **Description**: -Enables the [liquid alpha ](./consensus-based-weights) feature. +Enables the [liquid alpha ](../concepts/consensus-based-weights) feature. - - - ### MaxAllowedValidators - **Type**: u16 **Default**: 64 @@ -303,7 +328,6 @@ Enables the [liquid alpha ](./consensus-based-weights) feature. Maximum validators on a subnet. - ### MaxBurn **Type**: u64 @@ -319,7 +343,6 @@ Maximum validators on a subnet. **Description**: The maximum of the dynamic range for TAO cost of burn registration on the subnet. - ### MaxDifficulty @@ -327,9 +350,9 @@ The maximum of the dynamic range for TAO cost of burn registration on the subnet **Default**: 18446744073709551615 normalized to 1 -**`btcli` setter**: `btcli sudo set --param min_difficulty` +**`btcli` setter**: `btcli sudo set --param max_difficulty` -**Setter extrinsic**: +**Setter extrinsic**: `sudo_set_max_difficulty` **Permissions required to set**: Subnet creator @@ -353,10 +376,8 @@ The maximum of the dynamic range for difficulty of proof-of-work registration on Maximum neuron registrations per block. Note: Actual limit may be lower, as there is also per interval limit `TargetRegistrationsPerInterval`. - ### MaxWeightsLimit - **Type**: u16 **Default**: 65535 @@ -386,7 +407,6 @@ Minimum number of weights for a validator to set when setting weights. ### MinBurn - **Type**: u64 **Default**: 500000 normalized to 0.0005(τ) @@ -396,7 +416,7 @@ Minimum number of weights for a validator to set when setting weights. **Setter extrinsic**: `sudo_set_min_burn` **Permissions required to set**: Subnet creator - + **Description**: The minimum of the range of the dynamic burn cost for registering on the subnet. @@ -435,17 +455,15 @@ The minimum of the range of the proof-of-work for registering on the subnet `NetworkPowRegistrationAllowed` is a flag that toggles PoW registrations on a subnet - ### NetworkRateLimit - **Type**: u64 **Default**: 7200 **`btcli` setter**: none -**Setter extrinsic**: +**Setter extrinsic**: **Permissions required to set**: root @@ -453,7 +471,6 @@ The minimum of the range of the proof-of-work for registering on the subnet Rate limit for network registrations expressed in blocks - ### NetworkRegistrationAllowed **Type**: Boolean @@ -462,7 +479,7 @@ Rate limit for network registrations expressed in blocks **`btcli` setter**: `btcli sudo set --param registration_allowed` -**Setter extrinsic**: `sudo_set_network_registration_allowed` +**Setter extrinsic**: `sudo_set_network_registration_allowed` **Permissions required to set**: Subnet creator @@ -470,18 +487,15 @@ Rate limit for network registrations expressed in blocks `NetworkRegistrationAllowed` determines if burned registrations are allowed. If both burned and pow registrations are disabled, the subnet will not get emissions. - - ### Rho - **Type**: u16 **Default**: 10 -**`btcli` setter**: yes +**`btcli` setter**: `btcli sudo set --param rho` -**Setter extrinsic**: `sudo_set_rho` +**Setter extrinsic**: `sudo_set_rho` **Permissions required to set**: Subnet creator @@ -493,14 +507,13 @@ Deprecated. ### ServingRateLimit - **Type**: u16 **Default**: 50 -**`btcli` setter**: +**`btcli` setter**: `btcli sudo set --param serving_rate_limit` -**Setter extrinsic**: `sudo_set_serving_rate_limit` +**Setter extrinsic**: `sudo_set_serving_rate_limit` **Permissions required to set**: Subnet creator @@ -508,9 +521,38 @@ Deprecated. Rate limit for calling `serve_axon` and `serve_prometheus` extrinsics used by miners. +### OwnerHyperparamRateLimit -### TargetRegistrationsPerInterval +**Type**: u16 + +**Default**: 2 (tempos) + +**`btcli` setter**: none + +**Setter extrinsic**: `sudo_set_owner_hparam_rate_limit` + +**Permissions required to set**: Root + +**Description**: +Global multiplier that rate-limits how frequently a subnet owner can update subnet hyperparameters. The cooldown window equals `Tempo(netuid) × OwnerHyperparamRateLimit` blocks. The rate limit is tracked independently per hyperparameter; changing `kappa` does not block an immediate change to `rho`, for example. + +### SubnetIsActive + +**Type**: Bool + +**Default**: False + +**`btcli` setter**: `btcli subnets start` + +**Setter extrinsic**: nil + +**Permissions required to set**: Subnet creator + +**Description**: +Indicates whether or not the subnet's emissions have started. + +### TargetRegistrationsPerInterval **Type**: u16 @@ -526,7 +568,6 @@ Rate limit for calling `serve_axon` and `serve_prometheus` extrinsics used by mi Maximum number of neuron registrations allowed per interval. Interval is `AdjustmentInterval` - ### Tempo **Type**: u16 @@ -542,18 +583,17 @@ Maximum number of neuron registrations allowed per interval. Interval is `Adjust **Description**: Length of subnet tempo in blocks. -See [Emission](../emissions.md) +See [Emission](../learn/emissions.md) ### ToggleTransfer - **Type**: Boolean **Default**: True -**`btcli` setter**: none +**`btcli` setter**: btcli sudo set --param transfers_enabled` -**Setter extrinsic**: `sudo_set_toggle_transfer` +**Setter extrinsic**: `sudo_set_toggle_transfer` **Permissions required to set**: Subnet creator @@ -561,6 +601,22 @@ See [Emission](../emissions.md) Allows/disallows transfer of stake between coldkeys. +### UserLiquidityEnabled + +**Type**: Bool + +**Default**: False + +**`btcli` setter**: `btcli sudo set --param user_liquidity_enabled` + +**Setter extrinsic**: `toggle_user_liquidity` + +**Permissions required to set**: Subnet creator + +**Description**: + +Determines whether or not the user liquidity feature is enabled on the subnet. + ### WeightsVersion **Type**: u16 @@ -587,7 +643,7 @@ If the version key specified in `set_weights` extrinsic is lower than this syste **`btcli` setter**: `btcli sudo set --param weights_rate_limit` -**Setter extrinsic**: +**Setter extrinsic**: `sudo_set_weights_set_rate_limit` **Permissions required to set**: Root @@ -595,6 +651,22 @@ If the version key specified in `set_weights` extrinsic is lower than this syste How long, in blocks, a validator must wait between weight commits on a subnet. +### YumaVersion + +**Type**: Bool + +**Default**: False + +**`btcli` setter**: `btcli sudo set --param yuma_version` + +**Setter extrinsic**: `sudo_set_yuma3_enabled` + +**Permissions required to set**: Subnet Creator + +**Description**: + +Toggles the consensus mechanism used by the subnet between Yuma Consensus v2 and v3. + ## Global/Root State Variables The following variables are global and/or can only be configured with `root` permissions, which are held by a triumvirate of Opentensor Foundation employees. They are listed here for reference. @@ -603,7 +675,7 @@ The following variables are global and/or can only be configured with `root` per **Type**: u12 -**Default**: +**Default**: **`btcli` setter**: no @@ -615,77 +687,74 @@ The following variables are global and/or can only be configured with `root` per The duration in blocks of the waiting period before a coldkey swap. -See [Rotate/Swap your Coldkey](./schedule-coldkey-swap) +See [Rotate/Swap your Coldkey](../keys/schedule-coldkey-swap) + -### Issuance +### DissolveNetworkScheduleDuration -**Type**: u64 +Deprecated -**Description**: -Refers to total issuance, the amount of TAO in circulation. +### EmissionValue +**Description**: -### LockReductionInterval +Deprecated. replaced with SubnetAlphaInEmission, SubnetAlphaOutEmission, and SubnetTaoInEmission. +### EvmChainId -**Type**: u64 +**Permissions required to set**: root -**Default**: 14 * 7200 +**Description**: -**`btcli` setter**: +The Chain ID. `945` for Bittensor mainnet, a.k.a. Finney. -**Setter extrinsic**: +### Issuance -**Permissions required to set**: root +**Type**: u64 **Description**: +Refers to total issuance, the amount of TAO in circulation. -The number of blocks that need to pass in order for the network lock cost to half. - -`sudo_set_lock_reduction_interval`| root +### LockReductionInterval +**Type**: u64 +**Default**: 14 \* 7200 -### NetworkMinLockCost +**`btcli` setter**: -**`btcli` setter**: none - -**Setter extrinsic**: `sudo_set_network_min_lock_cost` +**Setter extrinsic**: **Permissions required to set**: root **Description**: -`NetworkMinLockCost` is the minimum TAO to pay for subnet registration - -### StakeThreshold - +The number of blocks that need to pass in order for the network lock cost to half. -**Type**: u12 +`sudo_set_lock_reduction_interval`| root -**Default**: 1000 +### NetworkMinLockCost **`btcli` setter**: none -**Setter extrinsic**: `sudo_set_stake_threshold` +**Setter extrinsic**: `sudo_set_network_min_lock_cost` **Permissions required to set**: root **Description**: -The minimum stake required for validating. Currently 1000 +`NetworkMinLockCost` is the minimum TAO to pay for subnet registration ### TxDelegateTakeRateLimit - **Type**: u64 **Default**: 216000 -**`btcli` setter**: +**`btcli` setter**: -**Setter extrinsic**: +**Setter extrinsic**: **Permissions required to set**: root @@ -693,30 +762,8 @@ The minimum stake required for validating. Currently 1000 Rate limit of how frequently can a delegate take be increased - - -### DissolveNetworkScheduleDuration - -Deprecated - -### EmissionValue - -**Description**: - -Deprecated. replaced with SubnetAlphaInEmission, SubnetAlphaOutEmission, and SubnetTaoInEmission. - -### EvmChainId - -**Permissions required to set**: root - -**Description**: - -The Chain ID. `945` for Bittensor mainnet, a.k.a. Finney. - - ### TxRateLimit - **Type**: u64 **Default**: 1000 @@ -731,16 +778,30 @@ The Chain ID. `945` for Bittensor mainnet, a.k.a. Finney. Rate limit for `swap_hotkey` extrinsic. - ### SubnetOwnerCut **`btcli` setter**: none **Setter extrinsic**: `sudo_set_subnet_owner_cut` -**Permissions required to set**: root +**Permissions required to set**: root **Description**: The ratio of all subnet alpha emissions that is given to subnet owner as stake. (Global, fixed at 18%.) +### StakeThreshold + +**Type**: u12 + +**Default**: 1000 + +**`btcli` setter**: none + +**Setter extrinsic**: `sudo_set_stake_threshold` + +**Permissions required to set**: root + +**Description**: + +The minimum stake required for validating. Currently 1000 diff --git a/docs/subnets/uid-trimming.md b/docs/subnets/uid-trimming.md new file mode 100644 index 0000000000..846fe1151e --- /dev/null +++ b/docs/subnets/uid-trimming.md @@ -0,0 +1,121 @@ +--- +title: "UID Trimming" +--- + +# UID Trimming + +UID trimming is a subnet management feature that allows subnet owners to reduce the number of neuron UIDs registered on their subnet, compressing the remaining UIDs to maintain consecutive indexing. UID trimming safely preserves high-performing and immune neurons, + +:::info UID trimming rate limit +The chain's trim UID rate limit is 216,000 blocks (~30 days). Therefore, subnet owners can only make changes to their UID count every 30 days. + +See [Rate Limits in Bittensor](../learn/chain-rate-limits.md). +::: + +- **Preserves Immune UIDs**: Both temporally immune UIDs and owner-owned UIDs are protected from trimming +- **Emission-Based Selection**: UIDs are trimmed based on their emission scores, removing the lowest performers +- **UID Compression**: After trimming, remaining UIDs are compressed to the left to maintain consecutive indexing +- **Storage Migration**: All associated storage is properly migrated and cleaned up +- **Configurable Limits**: Subnet owners can set minimum and maximum allowed UID counts + +:::info + +- The minimum UID count to which subnet owners can trim is currently 64. +- The maximum number of immune UIDs must not exceed 80% of the maximum UID count. + ::: + +## Emission-Based Selection + +UIDs are sorted by their emission scores in descending order. The trimming process: + +1. **Identifies Low Performers**: Starts from the lowest emitters and works upward +2. **Skips Immune UIDs**: Bypasses any UIDs that are temporally or owner immune +3. **Respects Limits**: Ensures the final count doesn't exceed the maximum allowed UIDs + +## For Subnet Owners + +Subnet trim UIDs using [`btcli sudo trim`](#uid-trimming-with-btcli) or the `sudo_trim_to_max_allowed_uids` extrinsic. + +**What happens:** + +- Owner-controlled UIDs are protected +- Recently registered UIDs (within immunity period) are protected +- UIDs with the lowest emission scores are removed first +- Remaining UIDs are compressed to maintain consecutive indexing +- All associated data (weights, bonds, etc.) is properly migrated + +## For Miners and Validators + +### Protection from Trimming + +You are protected from trimming if you have: + +1. **Temporal Immunity**: You registered recently (within the subnet's immunity period) +2. **Owner Immunity**: Your UID is owned by the subnet owner (up to a configurable limit) +3. **High Emissions**: Only low emissions neurons can be trimmed. + +### What Happens When Your UID Gets Trimmed + +When your UID is trimmed, all of your neuron data is **permanently deleted** from the blockchain, including: + +- UID-to-hotkey mapping +- Block registration timestamp +- Emission (incentive and dividends) history +- All weights you set to other neurons (Validators only) +- All bonds other neurons (Validators) had to you (Miners) +- Axon information (IP, port, etc.) +- Neuron certificates +- Prometheus metrics +- Last update timestamps + +**Your UID number will be reassigned** - the remaining UIDs are compressed to maintain consecutive numbering (e.g., if UIDs 5, 7, 9 remain after trimming, they become UIDs 0, 1, 2). + +### After Trimming + +If your UID was trimmed: + +- You must re-register to participate again +- You will receive a new UID number +- You start fresh with default scores + +### Source Code References + +- **Core Implementation**: `subtensor/pallets/subtensor/src/subnets/uids.rs` + +## UID trimming with BTCLI + +The `btcli sudo trim` command allows subnet owners to reduce the number of active UIDs on their subnet by trimming excess UIDs down to a specified maximum limit. + +:::warning Subnet Owner Only +This is a **sudo operation** that can only be performed by the subnet owner (the wallet that created the subnet). +::: + +### Basic usage + +```shell +btcli sudo trim --netuid --max +``` + +### Example + + +To trim subnet 14 on a local chain to a maximum of 100 UIDs: + +```shell +btcli sudo trim --netuid 14 --max 100 +``` +``` +You are about to trim UIDs on SN3 to a limit of 100 [y/n] (n): y +✅ Successfully trimmed UIDs on SN3 to 100 +``` + +The command will: + +1. Verify that your wallet owns the specified subnet +2. Display a confirmation prompt showing the trim operation details +3. Execute the trim operation if confirmed +4. Display the result of the operation + +:::note Transaction Fees +UID trimming operations incur transaction fees for the underlying blockchain transactions they trigger. See [Transaction Fees in Bittensor](../learn/fees.md) for details. +::: diff --git a/docs/subnets/understanding-multiple-mech-subnets.md b/docs/subnets/understanding-multiple-mech-subnets.md new file mode 100644 index 0000000000..9a3e7f350c --- /dev/null +++ b/docs/subnets/understanding-multiple-mech-subnets.md @@ -0,0 +1,151 @@ +--- +title: "Multiple Incentive Mechanisms Within Subnets" +--- + +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Multiple Incentive Mechanisms Within Subnets + +This page explores how subnets can implement multiple incentive mechanisms to distribute emissions across different evaluation criteria. + +:::tip Hot new feature +Multiple incentive mechanisms per subnet is a new feature that is still in development. It's initial release on mainnet is expected the week of September 22. In the meantime, it can be experimented with using a locally run chain. + +See [Announcements](../learn/announcements) for updates. +::: + +For an introduction to incentive mechanisms in general, see [Understanding Incentive Mechanisms](../learn/anatomy-of-incentive-mechanism). For the basics of subnets, miners, validators, and the blockchain, see [Components of the Bittensor platform](../learn/neurons). + +For coverage of the procedures involved, see: +- [Managing Mechanisms with SDK](./managing-mechanisms-with-sdk) +- [Managing Mechanisms with BTCLI](./managing-mechanisms-btcli) + +Historically, each subnet operates with a single **incentive mechanism**, a function that validators run to assign weights to miners based on the value of their work. Subnets can now support **multiple incentive mechanisms**, allowing a subnet creator to apportion the subnet's emissions across different evaluation criteria, each running Yuma Consensus _independently_ with separate bond pools to evaluate miners' performance on distinct tasks. + +Each miner receives emissions separately from each incentive mechanism, so a miner's performance in one mechanism does not affect their rating in another, and their emissions for each epoch are summed across all mechanisms. Validators receive dividends as a weighted sum of their performance across all incentive mechanisms - they cannot choose which mechanisms to validate, and if they don't validate all mechanisms, they receive proportionally reduced emissions. Multiple incentive mechanisms don't change the total emissions to a subnet, but create a way for subnet creators to distribute those emissions to miners working on different tasks. This mechanism affords subnet creators a transparent, on-chain way to exercise fine-grained control over the work they are incentivizing, keeping miner effort focused on work that is most needed at a time. + +Each incentive mechanism has its own: + +- **Weight matrix**: Each validator sets weights for each miner on each of the subnet's incentive mechanisms. +- **Independent bond pools**: Each mechanism maintains separate bonding relationships for Yuma Consensus calculations. +- **Independent emissions**: Since they depend on weights set by validators, a miner's emissions from each mechanism are independent. +- **Transparent on-chain data**: All incentive mechanism configurations and the flow of emissions are visible on-chain. +- **Emission distribution**: Subnet creators can control what percentage of total emissions goes to each mechanism using the `sudo_set_mechanism_emission_split` extrinsic. + +### Takeaways + +1. **Same Validators, Same Stake**: All validators participate in all incentive mechanisms within a subnet with identical stake weights. +2. **Same Miners**: All miners registered on a subnet can participate in any of its incentive mechanisms. +3. **Owner-Controlled Proportions**: The holder of the _subnet creator_ key sets the emission distribution among incentive mechanisms. +4. **Separate Bond Pools**: Each incentive mechanism maintains separate bonding relationships for independent Yuma Consensus calculations. + +:::note Current runtime limit +As of the current Subtensor runtime, a subnet can have a maximum of 2 mechanisms. It is planned to raised this cap in the future. +::: + +## What Should Stakers Know? + +**Core Impact:** + +- **No change to your staking mechanics**: Your stake is delegated to a validator on a subnet, and applies across all incentive mechanisms equally. +- **Same total emissions**: The subnet's total emissions remain unchanged - multiple mechanisms only redistribute these emissions internally among miners and validators. +- **Transparent allocation**: All emission proportions are visible on-chain, so you can see exactly how subnet owners are distributing emissions. + +**What This Means for Your Strategy:** + +- **No immediate action required**: Your existing staking strategy doesn't need to change +- **Enhanced monitoring**: You may want to track individual mechanism performance to understand subnet health +- **Risk assessment**: Factor in incentive mechanism design when evaluating subnet quality +- **Community oversight**: Use transparency to hold subnet owners accountable for fair emission distribution + +## What Should Miners Know? + +**Automatic Participation:** + +- **No separate registration**: When you register for a subnet, you are eligible to participate in any of its incentive mechanisms +- **Same UID across all mechanisms**: You use the same UID for all incentive mechanisms within a subnet + +**Performance Tracking:** + +- **Independent scoring**: Your performance is independent across different mechanisms, e.g. mechanism 0 doesn't affect your rating in mechanism 1. +- **Separate incentive columns**: You'll see individual incentive amounts for each mechanism in metagraph data. +- **Cumulative emissions**: Your total emissions = sum of emissions from all mechanisms where you participate. + +## What Should Validators Know? + +### Core Changes + +- **Separate weight setting**: You must set weights independently for each incentive mechanism. +- **Independent evaluation**: Each mechanism requires separate assessment according to its specific criteria. +- **Separate bond pools**: Each mechanism maintains independent bonding relationships for Yuma Consensus calculations. +- **Same stake weight**: Your stake weight is identical across all mechanisms - no additional stake required. +- **Weighted dividend calculation**: Your dividends are calculated as a weighted sum of your performance across all mechanisms. If you don't validate on all mechanisms, you will receive proportionally reduced emissions. + +### Operational Changes + +**1. Evaluation Workload:** + +- **Multiple assessments**: You must evaluate miners separately for each mechanism's tasks +- **Different criteria**: Each mechanism may have distinct evaluation standards + +**2. Data Structure Changes:** + +- **Two-dimensional weights**: Weights are now set for each miner on each mechanism. +- **Separate incentive tracking**: Each mechanism tracks incentives independently +- **Extended metagraph**: New columns for mechanism weights and incentives + +## What Should Subnet Creators/Developers Know? + +### Core Changes + +- **Emission distribution**: You can control what percentage of total emissions goes to each incentive mechanism using the `sudo_set_mechanism_emission_split` extrinsic. When the number of mechanisms is set, the emission distribution is reset to an even split, but you can set it again with custom proportions. + + :::info + The `sudo_set_mechanism_emission_split` extrinsic accepts an optional vector parameter. If the parameter is `None`, the distribution is set to an even split. When it's not `None`, it reflects the proportion of emissions each mechanism gets. The proportion is calculated as `value / 65535`. For example, in a subnet with two mechanisms and vector `[13107, 52428]`, mechanism 0 gets 20% and mechanism 1 gets 80%. + ::: + +- **Incentive mechanism design**: You define the specific tasks and evaluation criteria for each mechanism +- **Transparent configuration**: All mechanism settings are visible on-chain for community oversight +- **Single subnet slot**: No need to register multiple subnets for multiple competitions +- **Immediate mechanism number setting**: The number of mechanisms is set immediately when changed. +- **Rate limiting**: Subnet owners can set the number of mechanisms once per 7200 blocks (24 hours) on mainnet. See [Rate Limits in Bittensor](../learn/chain-rate-limits.md). + +:::tip +Ensure proportions sum to 100% when setting them, or the request will be rejected. +::: + +## Example Emissions Split + +For each subnet, the subnet creator keeps 18% of emissions, 41% is allocated to miners, and 41% to validators and their stakers, unless the subnet creator has reduced their take. Of the 41% that goes to miners and validators, here is an estimated emission distribution across three incentive mechanisms for each 100 $\tau$ earned on the subnet: + +:::info +Note that currently, only 2 mechanisms are allowed per subnet; it is planned that this cap will be raised in the future. +::: + +- Mechanism 0 (60%): 100 $\tau$ X .41 X .6 = 24.6 +- Mechanism 1 (30%): 100 $\tau$ X .41 X .3 = 12.3 +- Mechanism 2 (10%): 100 $\tau$ X .41 X .1 = 4.1 + +:::info Setting Custom Proportions +To achieve the above distribution, the subnet owner would submit the `sudo_set_mechanism_emission_split` extrinsic with the vector `[39321, 19660, 6554]` (calculated as 60% × 65535, 30% × 65535, 10% × 65535). +::: + +Note that a miner who excels in mechanism 0 but performs poorly in others might receive more emissions than a miner who performs moderately across all mechanisms, depending on the emission proportions and their relative performance. + +## On-Chain Data Structure + +Multiple incentive mechanisms extend the existing metagraph with additional columns: + +``` +UID | Hotkey | Stake | Mechanism 0 Weights | Mechanism 1 Weights | Mechanism 0 Incentive | Mechanism 1 Incentive +-----|--------|-------|---------------------|---------------------|----------------------|---------------------- +123 | 5ABC...| 1000 | [0.3, 0.2, 0.1...] | [0.1, 0.4, 0.2...] | 0.05 τ | 0.02 τ +456 | 7DEF...| 800 | [0.2, 0.3, 0.2...] | [0.2, 0.3, 0.1...] | 0.03 τ | 0.04 τ +``` + +## Backward Compatibility + +- Existing subnets continue with only one incentive mechanism (mechanism 0) collecting all emissions by default +- All existing API calls default to mechanism 0 +- No breaking changes to current functionality diff --git a/docs/subnets/understanding-subnets.md b/docs/subnets/understanding-subnets.md index a7930a1e85..6d1f1cb357 100644 --- a/docs/subnets/understanding-subnets.md +++ b/docs/subnets/understanding-subnets.md @@ -7,17 +7,18 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; # Understanding Subnets -In Bittensor, a subnet is an incentive-based competition marketplace that produces a specific kind of digital commodity related to artificial intelligence. It consists of a community of miners that produce the commodity, and a community of validators that measures the miners' work to ensure its quality. Often, parties that serve as validators do so in order to run applications that make use of the services provided by the miners. +In Bittensor, a subnet is an incentive-based competition marketplace that produces a specific kind of digital commodity related to artificial intelligence. It consists of a community of miners that produce the commodity, and a community of validators that measure the miners' work to ensure its quality. Often, parties that serve as validators do so in order to run applications that make use of the services provided by the miners. Emissions of TAO (τ) from Bittensor—are distributed among miners and validators based on their performance within subnets, and based on the relative performance of subnets within Bittensor. ## Anatomy of a subnet The illustration below shows the main components of a subnet: + 1. A subnet's [incentive mechanism](../learn/anatomy-of-incentive-mechanism) defines the work that miners must perform, and the work that validators must perform to evaluate the miners' work. The incentive mechanism is unique to the subnet, and maintained off-chain by the subnet creator in the form of a code-repository that defines the interface for miners and validators to participate. For example, see [Subnet 1](https://github.com/macrocosm-os/prompting). 2. **Miners** perform some useful work as defined in the subnet's incentive mechanism. For example, in Subnet 1, miners serve chat prompt completion. 3. **Validators** independently evaluate the task performed by the subnet miners, according to standards defined by the subnet's incentive mechanism. -4. Validators each score the performance of of each miner over the most recent time period. The matrix of these scores, by each validator for each miner, serves as input to **Yuma Consensus**. +4. Validators each score the performance of each miner over the most recent time period. The matrix of these scores, by each validator for each miner, serves as input to **Yuma Consensus**. 5. The Yuma Consensus algorithm operates on-chain, and determines emissions to miners, validators, and subnet creators across the platform, based on performance.
@@ -31,23 +32,24 @@ style={{width: 600}} />
-## Subnet liquidity reserves +## Liquidity pools -The key mechanism introduced with Dynamic TAO is that each subnet functions as its own automated market marker (AMM), with two liquidity reserves, one containing TAO($$\tau$$)—the currency of the Bittensor network, and one containing a subnet specific "dynamic" currency, referred to as that subnet's alpha ($$\alpha$$) token. The alpha token is purchased by staking TAO into the subnet's reserve, which is initialized with a negligible amount of liquidity (1e-9). +Each subnet functions as its own _automated market maker_ (_AMM_), with two liquidity reserves, one containing TAO($$\tau$$)—the currency of the Bittensor network, and one containing a subnet specific "dynamic" currency, referred to as that subnet's alpha ($$\alpha$$) token. The alpha token is purchased by staking TAO into the subnet's reserve, which is initialized with a negligible amount of liquidity (1e-9). A subnet's economy therefore consists of three pools of currency: + - **Tao reserves**: the amount of tao ($$\tau$$) that has been staked into the subnet - **Alpha reserves**: the amount of alpha ($$\alpha$$) available for purchase -- **Alpha outstanding**: the amount of alpha ($$\alpha$$) held in the hotkeys of a subnet's participants, also referred to as the total *stake* in the subnet +- **Alpha outstanding**: the amount of alpha ($$\alpha$$) held in the hotkeys of a subnet's participants, also referred to as the total _stake_ in the subnet :::tip Terminology: alpha tokens Each subnet has its own currency with its own name, but in the abstract a given subnet's token is referred to as its $\alpha$ token. With a set of subnets in mind, we refer to $\alpha$ as the token for subnet $\alpha$, $$\beta$$ as the token for subnet $$\beta$$, $$\gamma$$ as the token for subnet $$\gamma$$, and so on. These subnet tokens contrast with TAO ($$\tau$$), the token of the Bittensor network as a whole. A subnet pool's reserve ratio (tao/alpha) determines the price of its alpha token. ::: -The *price* of a subnet's alpha token is determined by the ratio of TAO in that subnet's reserve to its alpha in reserve. Alpha currency that is not held in reserve but is which is held in the hotkeys of subnet participants is referred to as *alpha outstanding*. +The _price_ of a subnet's alpha token is determined by the ratio of TAO in that subnet's reserve to its alpha in reserve. Alpha currency that is not held in reserve but is which is held in the hotkeys of subnet participants is referred to as _alpha outstanding_. -Run `btcli subnet list` with the Dynamic TAO-enabled `btcli` to view information about the subnets and their currency reserves on Bittensor testnet. +Run the `btcli subnet list` command with the Dynamic TAO-enabled `btcli` to view information about the subnets and their currency reserves on Bittensor testnet. ```txt ┃ ┃ Price ┃ Market Cap ┃ ┃ ┃ ┃ ┃ @@ -61,54 +63,61 @@ Run `btcli subnet list` with the Dynamic TAO-enabled `btcli` to view information 4 │ δ targon │ 0.02 τ/δ │ τ 54.45 │ τ 0.0192 │ τ 30.65, 1.47k δ │ 1.14k δ │ 2.61k δ /21M │ 68/99 ... ``` -See: [Using Dynamic TAO](./index.md#using-dynamic-tao) ## Price/rate of alpha tokens ### Ideal price -For each subnet, you'll see that *Price* (listed in the third column) is a function of TAO in reserve `τ_in` over alpha in reserve `α_in` + +For each subnet, you'll see that _Price_ (listed in the third column) is a function of TAO in reserve `τ_in` over alpha in reserve `α_in` $$ Price = \frac{\tau_{in}}{\alpha_{in}} $$ -For example, if for subnet $\varepsilon$, its subnet pool contains TAO reserves of 1000 TAO units and its alpha reserves of 16000 $\varepsilon$ units, then the relative price of the $\varepsilon$ token is: +
+ See how it's calculated! -$$ -R = \frac{\tau_{in}}{\alpha_{in}} = \frac{1000}{16000} = 0.0625 -$$ + For example, if for subnet $\varepsilon$, its subnet pool contains TAO reserves of 1000 TAO units and its alpha reserves of 16000 $\varepsilon$ units, then the relative price of the $\varepsilon$ token is: -Hence, -$$ -\text{1 } \varepsilon = 0.0625 \text{ TAO} -$$ + $$ + R = \frac{\tau_{in}}{\alpha_{in}} = \frac{1000}{16000} = 0.0625 + $$ + + Hence, + + $$ + \text{1 } \varepsilon = 0.0625 \text{ TAO} + $$ This exchange rate can change every block when staking or unstaking or emissions occur on this subnet. -## Emission in Dynamic TAO +
+ +## Emissions in Bittensor Liquidity is steadily emitted into the Bittensor token economy according to an algorithm intended to foster growth while stabilizing prices and protecting them from manipulation. Each block: + - the chain emits TAO and injects it into the TAO reserves of the subnets. -- the chain emits alpha tokens at twice the base alpha emission rate (which starts at 1 α/block and follows the same halving schedule as TAO). These emitted alpha tokens are allocoated between: +- the chain emits alpha tokens at twice the base alpha emission rate (which starts at 1 α/block and follows the same halving schedule as TAO). These emitted alpha tokens are allocated between: - the subnet's alpha reserve (increasing available liquidity) - alpha outstanding (incentives for miners, validators, and subnet creators) -See the main article: [Emission in Dynamic TAO](../emissions.md) +See [Emissions](../learn/emissions.md). ## Decentralized evaluation of subnets -The relative value or *weight* of subnets within Bittensor is critically important as it determines emissions to different subnets and their participant miners and validators. Prior to Dynamic TAO, relative weight among subnets within the Bittensor network were determined by Yuma Consensus over the evaluations of the Root Network validators. This gives a fundamentally centralizing role to the holders of Root Network validator keys. +The relative value or _weight_ of subnets within Bittensor is critically important as it determines emissions to different subnets and their participant miners and validators. Prior to Dynamic TAO, relative weight among subnets within the Bittensor network were determined by Yuma Consensus over the evaluations of the Root Network validators. This gives a fundamentally centralizing role to the holders of Root Network validator keys. In Dynamic TAO, the relative weight is determined organically according to the emergent market value of the subnet, as represented by its stabilized token price. TAO-holders can stake TAO into subnets in exchange for the subnet-specific dynamic currency, referred to as the subnet's alpha ($$\alpha$$) token. In this way, stakers 'vote with their TAO' for the value of the subnet, determining the emissions to the validators and miners working in it. In return, stakers extract a share of the subnet's emissions. ## Subnet Zero -In Dynamic TAO, Subnet Zero—or *Root Subnet*—is a special subnet. It is the only subnet that does not have its own $\alpha$ currency. No miners can register on subnet zero, and no validation work is performed. However validators can register, and $\tau$-holders can stake to those validators, as with any other subnet. This offers a mechanism for $\tau$-holders to stake $\tau$ into validators in a subnet-agnostic way. This works because the weight of a validator in a subnet includes both their share of that subnet's $\alpha$ and their share of TAO staked into the root subnet. in Subnet Zero. +In Dynamic TAO, Subnet Zero—or _Root Subnet_—is a special subnet. It is the only subnet that does not have its own $\alpha$ currency. No miners can register on subnet zero, and no validation work is performed. However validators can register, and $\tau$-holders can stake to those validators, as with any other subnet. This offers a mechanism for $\tau$-holders to stake $\tau$ into validators in a subnet-agnostic way. This works because the weight of a validator in a subnet includes both their share of that subnet's $\alpha$ and their share of TAO staked into the root subnet. -Over time, the emissions generated by TAO staked into Subnet Zero will decrease, relative to stake held in the alpha currency of active subnets. See [Note on evolution of Bittensor token economy](../emissions.md#note-on-evolution-of-bittensor-token-economy). +Over time, the emissions generated by TAO staked into Subnet Zero will decrease, relative to stake held in the alpha currency of active subnets. See [Note on evolution of Bittensor token economy](../learn/emissions.md#note-on-evolution-of-bittensor-token-economy). ## Validator stake weight @@ -116,9 +125,11 @@ A validator's stake weight in a subnet equals their alpha stake plus their TAO s $$ -\text{Validator stake weight} = \text{Alpha stake} (\alpha) + \text{TAO stake} (\tau) \times \text{TAO weight} +\text{Validator stake weight} = \text{Alpha stake} (\alpha) + \text{TAO stake} (\tau) \times \text{TAO weight} + $$ + :::tip A validator's stake weight in Subnet Zero is simply their staked TAO. ::: @@ -127,9 +138,10 @@ A validator's relative stake weight (their stake weight over the total stake wei $$ -\text{Validator x's relative stake weight} +\text{Validator x's relative stake weight} = \frac{\alpha_x + \tau_x \times w_{\tau}} {\displaystyle \sum_{v \in \text{validators}} \bigl(\alpha_v + \tau_v \times w_{\tau}\bigr)} + $$ diff --git a/docs/subnets/walkthrough-prompting.md b/docs/subnets/walkthrough-prompting.md index c0e7ff8b2a..93ee6be98e 100644 --- a/docs/subnets/walkthrough-prompting.md +++ b/docs/subnets/walkthrough-prompting.md @@ -1,13 +1,13 @@ --- -title: "Walkthrough of Subnet 1" +title: "Walkthrough of Example Subnet" --- import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; -# Walkthrough of Subnet 1 +# Walkthrough of Example Subnet -In this section we present a high-level walkthrough of the [Subnet 1: Prompting](https://github.com/opentensor/prompting/tree/main). This subnet contains multiple incentive mechanisms which produce an internet-scale conversational intelligence. Below are a few examples of the intelligence produced by this subnet: +This page presents a high-level walkthrough of an example architecture for a subnet based on LLM inference. This architecture was originally based on [Subnet 1, Apex](https://github.com/opentensor/prompting/tree/main), although subnets rapidly evolve and that subnet now has a more complicated architecture. This example subnet contains several incentive mechanisms which produce conversational intelligence capable of: - Answering questions. - Summarizing a given text. @@ -15,26 +15,24 @@ In this section we present a high-level walkthrough of the [Subnet 1: Prompting] - Translating languages. - Solve mathematics problems, and more. -This subnet is driven by large language models (LLMs). These LLMs search the internet and utilize specialized simulator modules to produce factually accurate and mathematically correct responses. +Our example subnet is driven by large language models (LLMs). These LLMs search the internet and utilize specialized simulator modules to produce factually accurate and mathematically correct responses. -:::tip Subnet 1 Explorer -You can see the prompting subnet in action on the [TAO.app explorer (select Subnet 01: Text Prompting from the top menu)](https://tao.app). +:::tip Explore the Subnets +Browse tokenomic information about the subnets on [TAO.app](https://tao.app), and learn more about the projects and services they support on the [Learnbittensor.org subnet listings](https://learnbittensor.org/subnets). ::: -## Before you proceed +**Prerequisites** If you are new to Bittensor subnets and building blocks, read the following sections before you proceed further: -- [Bittensor Building Blocks](../learn/bittensor-building-blocks). +- [Understanding Neurons](../learn/neurons). - [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism). -The below diagram shows a typical subnet with many subnet miners and subnet validators together executing the subnet incentive mechanism code. On the [TAO.app explorer (select Subnet 01: Text Prompting from the top menu)](https://tao.app) the **Metagraph** view for this Subnet 1: Prompting shows the performance details for each subnet miner and validator. - -For easier understanding, in this document we will focus on how a **single** subnet validator interacts with **multiple** subnet miners in this subnet. +The below diagram shows a typical subnet with many miners and validators together executing the incentive mechanism code. On the [TAO.app explorer](https://tao.app) the **Metagraph** view within a subnet's page shows the performance details for each subnet miner and validator. For example, visit [tao.app/subnets/14?active_tab=metagraph](https://www.tao.app/subnets/14?active_tab=metagraph) to view subnet 14's metagraph.
-## Subnet 1 summary +## Subnet Summary -See the below diagram showing a high-level view of how this Prompting subnet works. +See the below diagram showing a high-level view of how an example subnet works.
-The challenge generation works like this (see the above diagram): - The subnet validator generates a **prompt** consisting of a clearly stated question or a task description, for a given task type. - The subnet validator also generates one or more **reference** answers to the above prompt. The subnet validator also provides the context to generate this reference answer. -- A requirement for this prompting subnet is that the entire conversation should be human-like. To accomplish this, the subnet validator takes on a human persona and wraps the above prompt in the persona's style and tone. The introduction of such random persona's style and tone creates a lossy, corrupted, version of the original clear instruction. This corrupted prompt is called a **challenge**. -- The subnet validator prompts the subnet miners with this challenge. Note that the **reference** is not sent to the subnet miners. +- A requirement for this example subnet is that the entire conversation should be human-like. To accomplish this, the subnet validator takes on a human persona and wraps the above prompt in the persona's style and tone. The introduction of such random persona's style and tone creates a lossy, corrupted, version of the original clear instruction. This corrupted prompt is called a **challenge**. +- The subnet validator prompts the miners with this challenge. Note that the **reference** is not sent to the miners. -## Score the subnet miner responses +## Scoring the miners' responses -The responses from the subnet miners are compared to the reference answers by the subnet validator. The closer a subnet miner's response is to the reference answer, the higher is the subnet miner's score. +The responses from the miners are compared to the reference answers by the subnet validator. The closer a subnet miner's response is to the reference answer, the higher is the subnet miner's score. :::tip Measuring subnet miner's response -This Prompting Subnet 1 presently uses a combination of string literal similarity and semantic similarity as the basis for measuring the closeness of a subnet miner's response to the reference answer. +This example subnet uses a combination of string literal similarity and semantic similarity as the basis for measuring the closeness of a subnet miner's response to the reference answer. ::: -## Key innovations in this subnet +## Key subnet features -This subnet has developed a few innovative techniques to get to a real human-like conversational AI that actually produces intelligence instead of copying from the internet. Refer to the diagram in the above [Challenge generation](#challenge-generation) section: +This subnet demonstrates several design features that favor actually producing intelligence instead of copying from the internet. Refer to the diagram in the above [Challenge generation](#challenge-generation) section: ### Achieving human-like conversation To deliver to a user of this subnet an experience of a human-like conversation: -- Subnet validators perform a roleplay where they take on the persona of **random** human users before they prompt the subnet miners. There are several tangible benefits to this role playing flow, such as: - - Subnet validators can engage the subnet miners in a real, random, human-like conversation throughout the subnet operation. - - Subnet miners become adept at handling ambiguous instructions. +- Validators perform a roleplay where they take on the persona of **random** human users before they prompt the miners. There are several tangible benefits to this role playing flow, such as: + - Validators can engage the miners in a real, random, human-like conversation throughout the subnet operation. + - Miners become adept at handling ambiguous instructions. - This generates, as a byproduct, interesting synthetic datasets that can be used to finetune other LLMs. -- Subnet miners are required to produce completions that are as close as possible to the reference. To accomplish this a subnet miner must: +- Miners are required to produce completions that are as close as possible to the reference. To accomplish this a subnet miner must: - Extract clear instruction from the lossy challenge. - Find the appropriate context, for example, using Wikipedia. - Generate a completion that matches the tone and style of the reference. -- This means that throughout the subnet validation process the subnet miners become better and better at handling ambiguous, "fuzzy" instructions. +- This means that throughout the subnet validation process the miners become better and better at handling ambiguous, "fuzzy" instructions. - A subnet validator could increase the corruption of the instruction to increase the difficulty of the tasks. - To change the subnet miner completions, a subnet validator may modify the style and tone of the reference answers or change the scoring function, or both. +### Prevent miners from looking up the answers -:::tip Class HumanAgent -See [class HumanAgent](https://github.com/opentensor/prompting/blob/main/prompting/agent.py#L30). -::: - -### Prevent subnet miners from looking up the answers - -To prevent the subnet miners from simply looking up the answers on the internet, this subnet incorporates a novel approach—it introduces fuzziness into the prompt and requires that the subnet miners use semantic intelligence to understand the instructions contained in the prompt. +To prevent the miners from simply looking up the answers on the internet, this subnet introduces fuzziness into the prompt and requires that the miners use semantic intelligence to understand the instructions contained in the prompt. ### Evolve subnet as a mixture of experts (MoE) The subnet validator composes a challenge based on whether the task is answering questions, summarizing a given text, debugging code, solve mathematics problems, and so on. The motivation behind using multiple tasks is several fold: -- Using multiple tasks in the prompts continuously benchmarks the capabilities of the subnet miners across a broad range of tasks that are challenging but are still common use-cases. -- Using multiple tasks, prompts can be routed to specialized subnet miners, thereby providing an effective mixture of experts system. -- This approach also serves as a precursor to Bittensor's inter-subnet bridging mechanism that will enable Subnet 1 to interact with other subnets and access the useful work provided by these subnets. -- Finally, the subnet miners in this subnet must become adept at using tools and APIs in order to fulfill validation tasks. We are building an API layer for inter-subnet communication, which is a natural extension of 'agentic' models. +- Using multiple tasks in the prompts continuously benchmarks the capabilities of the miners across a broad range of tasks that are challenging but are still common use-cases. +- Using multiple tasks, prompts can be routed to specialized miners, thereby providing an effective mixture of experts system. +- Finally, the miners in this subnet must become adept at using tools and APIs in order to fulfill validation tasks. We are building an API layer for inter-subnet communication, which is a natural extension of 'agentic' models. :::tip Continuously improving performance -One objective of this subnet is to achieve full coverage of the distributions across different personas (representing different users), and different tasks (representing different use-cases). See the arXiv paper [Super-Natural Instructions](https://arxiv.org/abs/2204.07705) [(PDF)](https://arxiv.org/pdf/2204.07705.pdf). - +This example subnet is designed to achieve full coverage of the distributions across different personas (representing different users), and different tasks (representing different use-cases). See the arXiv paper [Super-Natural Instructions](https://arxiv.org/abs/2204.07705) [(PDF)](https://arxiv.org/pdf/2204.07705.pdf). ::: diff --git a/docs/subnets/working-with-subnets.md b/docs/subnets/working-with-subnets.md index 761a6114b8..8aa8dbfee6 100644 --- a/docs/subnets/working-with-subnets.md +++ b/docs/subnets/working-with-subnets.md @@ -4,10 +4,10 @@ title: "Working with Subnets" # Working with Subnets -Subnets are composed of a discrete number of UIDs. The subnet validators and subnet miners are associated with these UIDs. Each UID in the subnet belongs to a unique [hotkey](../getting-started/wallets.md#coldkey-and-hotkey) which in turn is connected to a unique **coldkey** which was used during registration. The Yuma Consensus runs on these UIDs. This section presents a few examples showing how to work with subnets. +Subnets are composed of a discrete number of UIDs. The subnet validators and subnet miners are associated with these UIDs. Each UID in the subnet belongs to a unique [hotkey](../keys/wallets.md#what-are-wallets-and-keys) which in turn is connected to a unique **coldkey** which was used during registration. The Yuma Consensus runs on these UIDs. This section presents a few examples showing how to work with subnets. -Transfer is transfer from cold to cold -Registration takes tao from cold +Transfer is transfer from cold to cold +Registration takes tao from cold Hotkey Tao movement is only stake add and remove and it’s loaded by emissions while mining Root delegation/undelegation is hotkey Tao movement to a strangers hotkey and it’s loaded by the activities of the strangers emission validation activities @@ -15,7 +15,7 @@ Root delegation/undelegation is hotkey Tao movement to a strangers hotkey and it Show all currently running subnets on Bittensor: -```bash +```bash btcli subnets list ``` @@ -41,7 +41,6 @@ assert subnet.uids.tolist() == [ 0, 1, 2, ... 1022, 1023 ] ## Extracting UID information - ```python import bittensor as bt subnet = bt.metagraph( netuid = 1 ) @@ -51,7 +50,7 @@ print ('uid', uid, ' owned by hotkey:', subnet.hotkeys[ uid ], 'associated with ## Viewing parameters -The below code prints stake `S` on the subnet and the weights `W` set by the subnet validators in the subnet. +The below code prints stake `S` on the subnet and the weights `W` set by the subnet validators in the subnet. ```python numbered dark import bittensor as bt @@ -62,7 +61,7 @@ print ('subnet 1 validator weights', subnet.W ) ## Viewing dividends -The below code prints the subnet validator dividends, `D`. +The below code prints the subnet validator dividends, `D`. ```python import bittensor as bt diff --git a/docs/subtensor-nodes/subtensor-rate-limits.md b/docs/subtensor-nodes/subtensor-rate-limits.md deleted file mode 100644 index e80734e3fb..0000000000 --- a/docs/subtensor-nodes/subtensor-rate-limits.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: "Subtensor Rate Limits" ---- - -# Subtensor Rate Limits - -We strongly encourage you to run your own local lite node. If you must query an OTF-provided lite node, then the following rate limits apply: - -- Any OTF-provided lite node will rate limit the requests to one request per second, per IP address. Note that this rate limit may change dynamically based on the network or application requirements. -- A request can be either WS/WSS or HTTP/HTTPS. -- If you exceed the rate limit, you will receive 429 error code. You will then have to wait until the rate limit window has expired. -- You can avoid OTF-lite node rate limits by running your own local lite node. You can run a lite node either [Using Docker](./using-docker.md#run-a-lite-node-on-mainchain) or [Using Source](./using-source.md#lite-node-on-mainchain). diff --git a/docs/subtensor-nodes/using-docker.md b/docs/subtensor-nodes/using-docker.md index 09e2d04261..21f8a49df5 100644 --- a/docs/subtensor-nodes/using-docker.md +++ b/docs/subtensor-nodes/using-docker.md @@ -1,109 +1,118 @@ --- title: "Using Docker" --- + import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; # Using Docker To run a subtensor node with Docker, follow the below steps. -:::danger Not tested on cloud -We have not tested subtensor node installation scripts on any cloud service. In addition, if you are using Runpod cloud service, then note that this service is already [containerized](https://docs.runpod.io/pods/overview). Hence, the only option available to you for Runpod is to install a subtensor node by [compiling from source](using-source.md). **Note that we have not tested any subtensor installation steps on Runpod.** +:::danger Not tested on cloud +We have not tested subtensor node installation scripts on any cloud service. In addition, if you are using Runpod cloud service, then note that this service is already [containerized](https://docs.runpod.io/pods/overview). Hence, the only option available to you for Runpod is to install a subtensor node by [compiling from source](using-source.md). **Note that we have not tested any subtensor installation steps on Runpod.** ::: -If you are already running a subtensor node using Docker, then go directly to [Step 5 Prepare to Run ](#step-5-prepare-to-run). The below steps 1 through 4 are for first time users only. - -## Step 1: Install git +## Prerequisites -Ensure that `git` is installed on your machine. Refer to the [GitHub documentation](https://docs.github.com/en/get-started) for installation instructions. +Before you begin, make sure you have installed the following on your machine: -## Step 2: Install Docker +- Install [Git](https://git-scm.com/downloads) +- [Docker](https://docs.docker.com/desktop/use-desktop/) -Follow Docker's [official installation guides](https://docs.docker.com/engine/install/) and install Docker. +The Bittensor SDK and Bittensor CLI are required to interact with the local blockchain instance. -:::tip Run Docker first -Before proceeding, make sure that Docker is running. -::: +## Step 1: Clone the subtensor repo -## Step 3: Clone the subtensor repo - -Clone the subtensor repository: +Clone the subtensor repository and navigate into the Subtensor directory: ```bash git clone https://github.com/opentensor/subtensor.git -``` - -## Step 4: Go into subtensor directory - -Navigate into the Subtensor directory: - -```bash cd subtensor ``` -## Step 5: Switch to `main` branch +:::tip Always Pull the Latest Changes -Execute the below commands in this order: +Before running the subtensor node, always ensure that you're working with the latest version of the repository. To do this, run the following command in the `subtensor` directory to fetch and merge the most recent updates: -Switch to the `main` branch: - -```bash -git checkout main -``` - -Pull the latest `main` branch contents: - -```bash +```sh git pull ``` -## Step 6: Stop and clean Docker environment +::: + +## Step 2: Clean Docker environment -Stop any currently running Docker containers and clean up the Docker environment: +Next, stop any currently running Docker containers and clean up the Docker environment using the following command: ```bash docker compose down --volumes && docker system prune -a --volumes -f ``` -## Linux post-installation steps for Docker Engine +:::warning Linux post-installation steps for Docker Engine +Please follow Docker's [official documentation](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user) to perform standard Linux post-installation steps for Docker Engine -Please follow Docker's [official documentation](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user ) to perform standard Linux post-installation steps for Docker Engine - -:::tip Adding a user to the `docker` group is only necessary on Linux, where `sudo` privileges are required to run Docker commands. It is unnecessary on macOS. ::: +## Step 3: Run the subtensor node + +Now you can run the subtensor nodes for either mainchain or testchain using any of available options. -## Run a Lite Node on Mainchain +### Using lite nodes -To run a lite node connected to the Bittensor mainchain, execute the below command. +A lite node which primarily syncs with the only blocks that have been finalized, and not the entire blockchain. Run a lite node using the command corresponding to your target chain: + + +To run a lite node connected to the Bittensor mainchain, run the following command: ```bash ./scripts/run/subtensor.sh -e docker --network mainnet --node-type lite ``` -## Run an Archive Node on Mainchain - -To run an archive node connected to the Bittensor mainchain, execute the below command. + + +To run a lite node connected to the Bittensor testchain, run the following command: ```bash -./scripts/run/subtensor.sh -e docker --network mainnet --node-type archive +./scripts/run/subtensor.sh -e docker --network testnet --node-type lite ``` -## Run a Lite Node on Testchain + + + +The command pulls the Subtensor Docker image and starts the container. + +:::warning Docker Resource Allocation +Ensure Docker is configured with sufficient CPU and memory resources to meet the system requirements for running a subtensor node. Inadequate allocation may prevent the node from starting correctly. + +We recommend allocating at least 20 GB of RAM. You can adjust these settings in Docker Desktop under **Settings** > **Resources**. +::: + +### Using archive nodes -To run a lite node connected to the Bittensor testchain, execute the below command. +An archive node downloads and validates all the Bittensor blockchain blocks from inception up to the most recent block. Run an archive node using the command corresponding to your target chain: + + + +To run an archive node connected to the Bittensor mainchain, run the following command: ```bash -./scripts/run/subtensor.sh -e docker --network testnet --node-type lite +./scripts/run/subtensor.sh -e docker --network mainnet --node-type archive ``` -## Run an Archive Node on Testchain - -To run an archive node connected to the Bittensor testchain, execute the below command. + + +To run an archive node connected to the Bittensor testchain, run the following command: ```bash ./scripts/run/subtensor.sh -e docker --network testnet --node-type archive ``` + + + + +The command pulls the Subtensor Docker image and starts the container. diff --git a/docs/subtensor-nodes/using-source.md b/docs/subtensor-nodes/using-source.md index e521b5036d..11385ef923 100644 --- a/docs/subtensor-nodes/using-source.md +++ b/docs/subtensor-nodes/using-source.md @@ -1,6 +1,7 @@ --- title: "Using Source Code" --- + import ThemedImage from '@theme/ThemedImage'; import useBaseUrl from '@docusaurus/useBaseUrl'; @@ -8,8 +9,8 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; To install and run a subtensor node by compiling the source code, follow the below steps. -:::danger Not tested on cloud -We have not tested subtensor node installation scripts on any cloud service. In addition, if you are using Runpod cloud service, then note that this service is already [containerized](https://docs.runpod.io/pods/overview). Hence, the only option available to you for Runpod is to install a subtensor node by compiling from source, as described below. **Note that we have not tested any subtensor installation steps on Runpod.** +:::danger Not tested on cloud +We have not tested subtensor node installation scripts on any cloud service. In addition, if you are using Runpod cloud service, then note that this service is already [containerized](https://docs.runpod.io/pods/overview). Hence, the only option available to you for Runpod is to install a subtensor node by compiling from source, as described below. **Note that we have not tested any subtensor installation steps on Runpod.** ::: ## Install basic packages @@ -17,7 +18,7 @@ We have not tested subtensor node installation scripts on any cloud service. In Install the basic requirements by running the below commands on a Linux terminal. ```bash title="Linux" -sudo apt-get update +sudo apt-get update sudo apt install -y build-essential clang curl git make libssl-dev llvm libudev-dev protobuf-compiler pkg-config ``` @@ -46,7 +47,7 @@ rustup toolchain install nightly rustup target add --toolchain nightly wasm32-unknown-unknown ``` -## Compile subtensor code +## Compile subtensor code Next, to compile the subtensor source code, follow the below steps: @@ -55,6 +56,7 @@ Next, to compile the subtensor source code, follow the below steps: ```bash git clone https://github.com/opentensor/subtensor.git ``` + 2. Change to the Subtensor directory: ```bash @@ -70,7 +72,7 @@ git checkout main 4. Remove any previous chain state: ```bash -rm -rf /var/lib/subtensor +rm -rf /var/lib/subtensor ``` 5. Install Subtensor by compiling with Cargo: @@ -83,34 +85,34 @@ cargo build -p node-subtensor --profile=production --features=metadata-hash You can now run the public subtensor node either as a lite node or as an archive node. See below: -### Lite node on mainchain +### Lite node on mainchain To run a lite node connected to the mainchain, execute the below command (note the `--sync=warp` flag which runs the subtensor node in lite mode): -```bash title="With --sync=warp setting, for lite node" -./target/production/node-subtensor --chain ./chainspecs/raw_spec_finney.json --base-path /var/lib/subtensor --sync=warp --port 30333 --max-runtime-instances 32 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /dns/bootnode.finney.chain.opentensor.ai/tcp/30333/ws/p2p/12D3KooWRwbMb85RWnT8DSXSYMWQtuDwh4LJzndoRrTDotTR5gDC --no-mdns --prometheus-external --rpc-external -``` +```bash +./target/production/node-subtensor --chain ./chainspecs/raw_spec_finney.json --base-path /var/lib/subtensor --sync=warp --port 30333 --max-runtime-instances 32 --database paritydb --db-cache 4096 --trie-cache-size 2048 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /dns/bootnode.finney.chain.opentensor.ai/tcp/30333/ws/p2p/12D3KooWRwbMb85RWnT8DSXSYMWQtuDwh4LJzndoRrTDotTR5gDC --no-mdns --rpc-external +``` ### Archive node on mainchain To run an archive node connected to the mainchain, execute the below command (note the `--sync=full` which syncs the node to the full chain and `--pruning archive` flags, which disables the node's automatic pruning of older historical data): -```bash title="With --sync=full and --pruning archive setting, for archive node" +```bash ./target/production/node-subtensor --chain ./chainspecs/raw_spec_finney.json --base-path /var/lib/subtensor --sync=full --pruning archive --port 30333 --max-runtime-instances 32 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /dns/bootnode.finney.chain.opentensor.ai/tcp/30333/ws/p2p/12D3KooWRwbMb85RWnT8DSXSYMWQtuDwh4LJzndoRrTDotTR5gDC --no-mdns --prometheus-external --rpc-external -``` +``` -### Lite node on testchain +### Lite node on testchain To run a lite node connected to the testchain, execute the below command: -```bash title="With bootnodes set to testnet and --sync=warp setting, for lite node." -./target/production/node-subtensor --chain ./chainspecs/raw_spec_testfinney.json --base-path /var/lib/subtensor --sync=warp --port 30333 --max-runtime-instances 32 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /dns/bootnode.test.finney.opentensor.ai/tcp/30333/ws/p2p/12D3KooWPM4mLcKJGtyVtkggqdG84zWrd7Rij6PGQDoijh1X86Vr --no-mdns --prometheus-external --rpc-external -``` +```bash +./target/production/node-subtensor --chain ./chainspecs/raw_spec_testfinney.json --base-path /var/lib/subtensor --sync=warp --port 30333 --max-runtime-instances 32 --database paritydb --db-cache 4096 --trie-cache-size 2048 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /dns/bootnode.test.finney.opentensor.ai/tcp/30333/ws/p2p/12D3KooWPM4mLcKJGtyVtkggqdG84zWrd7Rij6PGQDoijh1X86Vr --no-mdns --rpc-external +``` ### Archive node on testchain To run an archive node connected to the testchain, execute the below command: -```bash title="With bootnodes set to testnet and --sync=full and --pruning archive setting, for archive node" +```bash ./target/production/node-subtensor --chain ./chainspecs/raw_spec_testfinney.json --base-path /var/lib/subtensor --sync=full --pruning archive --port 30333 --max-runtime-instances 32 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /dns/bootnode.test.finney.opentensor.ai/tcp/30333/ws/p2p/12D3KooWPM4mLcKJGtyVtkggqdG84zWrd7Rij6PGQDoijh1X86Vr --no-mdns --prometheus-external --rpc-external -``` +``` diff --git a/docs/tutorials/ocr-subnet-tutorial.md b/docs/tutorials/ocr-subnet-tutorial.md index 5402367b9c..f946955eb6 100644 --- a/docs/tutorials/ocr-subnet-tutorial.md +++ b/docs/tutorials/ocr-subnet-tutorial.md @@ -53,7 +53,7 @@ For the rest of this tutorial we will proceed by demonstrating which blocks of P If you are new to Bittensor, read the following sections before you proceed: 1. [Introduction](../learn/introduction.md) that describes how subnets form the heartbeat of the Bittensor network. -2. [Bittensor Building Blocks](../learn/bittensor-building-blocks.md) that presents the basic building blocks you use to develop your subnet incentive mechanism. +2. [Bittensor Building Blocks](../learn/neurons.md) that presents the basic building blocks you use to develop your subnet incentive mechanism. 3. [Anatomy of Incentive Mechanism](../learn/anatomy-of-incentive-mechanism.md) that introduces the general concept of a subnet incentive mechanism. ## OCR subnet summary @@ -218,7 +218,7 @@ See the `OCRSynapse` class definition in [**ocr_subnet/protocol.py**](https://gi ``` :::tip Study tip -See [Neuron-to-neuron communication](../learn/bittensor-building-blocks.md#neuron-to-neuron-communication). +See [Neuron-to-neuron communication](../learn/neurons.md#neuron-to-neuron-communication). ::: #### Send OCRSynapse to miners diff --git a/docs/validators/child-hotkeys.md b/docs/validators/child-hotkeys.md new file mode 100644 index 0000000000..c306e207a1 --- /dev/null +++ b/docs/validators/child-hotkeys.md @@ -0,0 +1,227 @@ +--- +title: "Child Hotkeys" +toc_max_heading_level: 2 +--- + +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Child Hotkeys + +This guide describes the **child hotkeys** feature and how to use it. With the child hotkeys, a subnet validator is no longer required to use the same delegate hotkey for every subnet they validate in. The subnet validator can use a separate **child hotkey** per subnet. The subnet validator does this by re-delegating a portion of their stake from their delegate hotkey to this separate child hotkey on a subnet. The originating delegate hotkey is called the **parent hotkey**. + +The owner of this child hotkey would then validate in the subnet on behalf of the parent hotkey. The child hotkey would receive a percentage `take` from the resulting dividends. + +
+ +
+ +
+ +See the above diagram. Without the child hotkeys, a subnet validator's delegate hotkey would have to sign all the validation operations in all the subnets. This exposes the delegate hotkey in all the subnets. An attacker can get hold of the delegate hotkey from any one subnet in order to take over the validation operations with this hotkey, thereby crippling this subnet validator in all their subnets across the entire Bittensor network. + +
+ +
+ +See the above diagram. With the child hotkeys, if an attacker steals a child hotkey, then only those subnets are at risk where this child hotkey is used as the delegate hotkey. + +## Benefits of child hotkeys + +- **Security for parent hotkeys**: Re-delegating stake to multiple child hotkeys enhances the security of the parent hotkey. Each child hotkey can validate on a specific subnet using a different machine. The child hotkey would sign the validation operations on behalf of the parent hotkey: There is no need to use the parent hotkey on any of these subnets. As a consequence, the exposure of the parent hotkey can be minimized. The parent hotkey can even be moved to a secure location until it is needed, for example, to revoke a child hotkey. +- **Validators can easily scale up**: As Bittensor scales up towards hundreds of subnets, it is not practical for a single delegate to validate in every single subnet. With child hotkeys, a validator can easily make this feasible by re-delegating and offloading the validating operations to multiple child hotkeys. +- **Increased bandwidth for a subnet owner**: A validator can also re-delegate to a subnet owner's hotkey. The subnet owner would then do the validation work on the subnet, in exchange for a percentage `take` from the resulting dividends. A subnet owner can increase their access bandwidth into their own subnet in this way. +- A child hotkey and a parent hotkey need not be owned by the same entity. +- A validator can re-delegate to a hotkey of any other validator on any subnet. After re-delegation, the hotkey that is the source of the stake is called **parent hotkey** and the hotkey that receives this re-delegated stake is called **child hotkey**. + :::tip "Child hotkey" and "parent hotkey" are terms of convenience + The terms "child hotkey" and "parent hotkey" are only terms of convenience. There is nothing inherently different about a "child hotkey" that separates it from a "parent hotkey". Neither have any special attributes compared to a normal hotkey. + ::: + +## Features + +The child hotkey features are as follows: + +- A hotkey must be registered on a subnet before it can be used as a parent hotkey. The hotkey can be registered on any subnet. +- A parent hotkey can have multiple child hotkeys. Similarly, a child hotkey can have more than one parent hotkey. +- A child hotkey can exist as a registered hotkey in multiple netuids simultaneously. +- **IMPORTANT**: For a given `netuid`, say, `netuid 5`, a single parent hotkey can have at most five (`5`) child hotkeys. Moreover, the same parent hotkey on a different `netuid 11` can have another set of `5` child hotkeys. Alternately, on this `netuid 11` the same parent hotkey can also have the same (`5`) child hotkeys that are in the netuid `5`. +- While setting the child hotkeys, the proportion field can have proportions that add to less than `1.0`. The proportion that was not assigned to the child hotkeys will remain with the parent hotkey. However, a proportion cannot be zero. A `0` proportion value will result in an error. Furthermore, in a given subnet, the sum of all proportions must not exceed `1.0`. + +## Rate limits + +The following rate limits apply for child hotkeys: + +- Setting or revoking children is allowed for every 150 blocks (~30 minutes). +- A given child hotkey's take rate can only be adjusted once per 30 days. + +See [Rate Limits in Bittensor: Child hotkey operations rate limit](../learn/chain-rate-limits#child-hotkey-operations-rate-limit). + +## Minimum stake requirement + +To set child hotkeys, the parent hotkey must have a minimum total stake. This requirement checks the TAO-equivalent value of your alpha stake across all subnets. + +The minimum stake requirement is: + +- **Mainnet**: 1000 TAO worth of alpha +- **Testnet**: 100 TAO worth of alpha + +**How it's calculated**: Your alpha stake is summed **across ALL subnets** (not just the subnet where you're setting children). Each subnet's alpha is converted to TAO value using that subnet's alpha price, then all values are summed together. View [source code](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/staking/helpers.rs#L47-L62). + +:::tip +Query `subtensorModule.stakeThreshold()` to check the current threshold. +::: + +## Child hotkey commands + +Use the `btcli` command options described below to work with child hotkeys. + +## Setting a child hotkey + +You can allocate a portion of the parent hotkey’s stake weight to its child hotkeys, specifying the exact proportion for each one. The parent hotkey must be registered on at least one netuid, but it doesn’t have to be registered on the same netuid where the child weights are being set. However, all child hotkeys assigned must be registered on the netuid specified in the command. + +### Usage + +```bash +btcli stake child set --netuid --children
--proportions --hotkey --wallet.name +``` + +### Parameters + +- `--netuid:` The netuid of the subnet in the network. Value must be greater than zero. +- `--children`: A comma-separated ordered list of SS58 hotkeys for the child hotkeys. +- `--proportions`: A comma-separated ordered list of the stake weight proportions for the child hotkeys listed in the `--children` parameter. +- `--hotkey`: A single SS58 of the parent hotkey. This must be a delegate hotkey that is already registered in with any `netuid`. +- `--wallet.name`: Name of the wallet or the SS58 of the coldkey. This coldkey must be matched with the parent hotkey SS58 of the `--hotkey`. + +:::info + +- The `--children` and `--proportions` parameters can each include up to five comma-separated values. +- The sum of all proportion values for the child hotkeys should be less than or equal to 1. +- All hotkeys listed in the `--children` parameter must be already registered on the `netuid` used in this command. +- Only the staked TAO of the parent hotkey can be assigned to the child hotkeys. If the parent hotkey has zero stake, then the command will issue an error message and stop. + + ::: + +#### Setting a single child hotkey + +```bash +btcli stake child set \ + --netuid 4 \ + --children 5HEXVAHY9gyavj5xnbov9Qoba4hPJYkkwwnq1MQFepLK7Gei \ + --proportions 0.5 \ + --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ + --wallet.name Alice +``` + +#### Setting multiple child hotkeys + +```bash +btcli stake child set \ + --netuid 4 \ + --children 5Gx1CZ9jviC6V2KynBAcTpES4yK76riCagv5o5SFFZFYXj4s,5HEXVAHY9gyavj5xnbov9Qoba4hPJYkkwwnq1MQFepLK7Gei \ + --proportions 0.3,0.7 \ + --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ + --wallet.name Alice\ +``` + +## Adding a new child hotkey + +If a parent hotkey has, for example, three child hotkeys: `child hotkey A`, `child hotkey B` and `child hotkey C`, then to add a fourth—`child hotkey D`, you must run `btcli stake child set` command again with the parent hotkey and set the proportions for all four child hotkeys `A`, `B`, `C` and `D`. + +:::info Updating hotkey proportions +When updating the proportion of a child hotkey, you must rerun the `btcli stake child set` command with the parent hotkey and all existing child hotkeys, including their updated proportions. + +::: + +## Getting the child hotkeys + +Run the following command to display all the child hotkeys for a given parent hotkey. + +```bash +btcli stake child get +``` + +### Example usage + +```bash +btcli stake child get --netuid --hotkey --all +``` + +## Revoking the child hotkeys + +This is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet. + +:::info Revoking a specific child hotkey is not allowed +It is not possible to revoke a specific child hotkey. However, if a parent hotkey has, for example, three child hotkeys: `child hotkey A`, `child hotkey B` and `child hotkey C`, then setting the parent hotkey again with only child hotkeys `A` and `B` will result in revoking `child hotkey C`. +::: + +### Usage + +```bash +btcli stake child revoke +``` + +### Example + +```bash +btcli stake child revoke \ + --netuid 4 \ + --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ + --wallet.name Alice +``` + +## Get and set child hotkey take + +Each child hotkey can have a defined take percentage that determines the portion of rewards it receives on a given netuid. The take value can range from `0` (0%) to `0.18` (18%). This configuration is subnet-specific meaning that a child hotkey may have one take percentage on one netuid and a different value on another. + +The child hotkey can also set its delegate take separately from the child hotkey take. That is, a child hotkey can carry two separate take rates: the child hotkey take rate and the delegate take rate. For the delegate take rate, see [Set delegate take](../btcli/btcli.md#btcli-sudo-set-take). + +### Usage + +```bash +btcli stake child take +``` + +:::info +Running the command without the `--take` flag only retrieves the child hotkey's take on the subnet. To set the child hotkey take, you must run the command with the `--take` flag. +::: + +To set child hotkey take, run the following command: + +```bash +btcli stake child take \ + --netuid \ + --child-hotkey-ss58 \ + --take \ + --wallet.name +``` + +### Parameters + +- `--child-hotkey-ss58 `: A single SS58 of the child hotkey. If not provided, it assigns the take value to the hotkey of the signing wallet. +- `--take`: A value between `0` (0%) and `0.18` (18%). Default value is `0`. +- `--netuid`: The `netuid` in which this child hotkey's `take` is applicable. Note that a child hotkey's `take` is subnet-specific, i.e., a child hotkey can have one `take` in one `netuid` and a different `take` in another `netuid`. + +### Example + +```bash +btcli stake take child take \ + --netuid 4 \ + --hotkey 5DqJdDLU23m7yf6rZSmbLTshU7Bfn9eCTBkduhF4r9i73B9Y \ + --take 0.09 \ + --wallet.name Alice +``` diff --git a/docs/validators/index.md b/docs/validators/index.md index 2c39063479..7afb7a02de 100644 --- a/docs/validators/index.md +++ b/docs/validators/index.md @@ -7,12 +7,12 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; # Validating in Bittensor -All mining and validating in Bittensor occur within a subnet. Each subnet independently produces the digital commodities that are its purpose, each subnet creator defining a different _incentive mechanism_ for validators to use in judging miners' work. The validator's work is to apply this incentive mechanism to miners, using it to score their performance, and then to submit these weights to the Bittensor blockchain. It is validators scores of miners' performance that determines the proportion of the subnet's emissions allocated to each miner, according to the Yuma Consensus algorithm. See [Emissions](../emissions.md). +All validating in Bittensor occurs within a subnet. Each subnet independently produces the digital commodities that are its purpose, with each subnet creator defining a different _incentive mechanism_ for validators to use in judging miners' work. The validator's work is to apply this incentive mechanism to miners, using it to score their performance, and then to submit these weights to the Bittensor blockchain.  The validator scores of miners' performance determine the proportion of the subnet's emissions allocated to each miner, according to the Yuma Consensus algorithm. See [Emissions](../learn/emissions.md). Browse the subnets and explore links to their code repositories on [TAO.app' subnets listings](https://tao.app). :::tip Typical compute requirements -Each subnet may have distinct hardware requirements, but this [minimum requirements template for subnet creators](https://github.com/opentensor/bittensor-subnet-template/blob/main/min_compute.yml) may give an idea of minimum memory, bandwidth and storage requirements for a typical subnet node. +Each subnet may have distinct hardware requirements, but this [subnet minimum requirements template](https://github.com/opentensor/bittensor-subnet-template/blob/main/min_compute.yml#L49) may give an idea of the minimum memory, bandwidth and storage requirements for validators in a typical subnet node. Validating is not supported on Windows. ::: @@ -32,7 +32,7 @@ The number of validators isn't hardcoded. The subnet governor has the authority To have a **validator permit** in a given subnet, you must meet the following requirements: - Your hotkey must be registered, granting you a UID on the subnet -- You must have a stake-weight on the subnet of least 1000, including stake delegated to your hotkey from other wallets' coldkeys. A validator's stake weight in a subnet equals their alpha stake plus their TAO stake times the `tao_weight` parameter (current value: 0.18): +- You must have a stake-weight on the subnet of least 1000, including stake delegated to your hotkey from other wallets' coldkeys. A validator's stake weight in a subnet equals their alpha stake plus their TAO stake multiplied by the `tao_weight` parameter (current value: 0.18): $$ @@ -42,12 +42,14 @@ To have a **validator permit** in a given subnet, you must meet the following re - You must be one of the top 64 nodes in the subnet, ranked by emissions. -## Hotkey Association & Staking (subnet 0, the root subnet, only) +## Hotkey Association & Staking :::tip Root Subnet (Subnet 0) only -Skip this step if you are not registering a validator on the root subnet (subnet 0) +This step is only required if you are registering on the root subnet (Subnet O). Skip this step if you are not registering a validator on the root subnet. ::: +To become a validator on the root subnet, you must first associate your hotkey and then stake funds to your hotkey account within the subnet. To associate your hotkey: + ```bash btcli wallet associate-hotkey --wallet.name --hotkey ``` @@ -81,7 +83,7 @@ When a validator falls below the top 64 nodes by emissions, or has less than the Deregistration only occurs on subnets where all 256 UID slots are occupied. If a new registration occurs in a subnet with available UID slots, the registered neuron occupies one of the available UID slots. ::: -Each tempo, the '[neuron](../learn/bittensor-building-blocks)' (miner _or_ validator node) with the lowest 'pruning score' (based solely on emissions), and that is no longer within its [immunity period](../subnets/subnet-hyperparameters.md#immunityperiod), risks being replaced by a newly registered neuron, who takes over that UID. +Each tempo, the '[neuron](../learn/neurons)' (miner _or_ validator node) with the lowest 'pruning score' (based solely on emissions), and that is no longer within its [immunity period](../subnets/subnet-hyperparameters.md#immunityperiod), risks being replaced by a newly registered neuron, who takes over that UID. :::info Deregistration is based on emissions The subnet does not distinguish between miners and validators for the purpose of deregistration. The chain only looks at emissions (represented as 'pruning score'). Whenever a new registration occurs in the subnet, the neuron with the lowest emissions will get deregistered. @@ -93,6 +95,19 @@ Every subnet has an `immunity_period` hyperparameter expressed in a number of bl A subnet neuron (miner or validator) at a UID (in that subnet) has `immunity_period` blocks to improve its performance. When `immunity_period` expires, that miner or validator can be deregistered if it has the lowest performance in the subnet and a new registration arrives. +**Implementation Details:** + +Immunity status is calculated dynamically using the formula `is_immune = (current_block - registered_at) < immunity_period`, where: + +- `current_block` is the current blockchain block number +- `registered_at` is the block number when the neuron was registered +- `immunity_period` is the configured protection period for the subnet (default: 4096 blocks ≈ 13.7 hours) + +**Code References:** + +- [`subtensor/pallets/subtensor/src/utils/misc.rs:442-448`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/utils/misc.rs#L442-448) - Immunity status calculation +- [`subtensor/pallets/subtensor/src/subnets/registration.rs:409-485`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/registration.rs#L409-485) - Pruning algorithm with immunity priority + :::tip Special cases - In the unlikely event that all neurons are still immune, the one with the lowest "pruning score" will be deregistered by the next incoming registration. @@ -107,7 +122,7 @@ A subnet neuron (miner or validator) at a UID (in that subnet) has `immunity_per A validator's consensus weight and emissions depend on their hotkey's stake weight. You can stake your own TAO to your validator hotkey, or advertise your hotkey to others and seek stake. Any wallet's coldkey can stake to any hotkey, subsequently receiving emissions from that stake. :::tip Delegation -See [StakingDelegation](../staking-and-delegation/delegation.md) +See [Staking and Delegation](../staking-and-delegation/delegation.md) ::: ### Add stake @@ -138,9 +153,53 @@ import bittensor as bt subnet = bt.metagraph(1) wallet = bt.wallet( name = 'my_coldkey', hotkey = 'my_validator_hotkey' ) my_uid = subnet.hotkeys.index( wallet.hotkey.ss58_address ) -print(f'Validator permit: {subnet.validator_permit(my_uid)}') +print(f'Validator permit: {subnet.validator_permit[my_uid]}') ``` +## Validator Permits + +Validator permits control which neurons can participate in validation activities within a subnet. The system operates on a stake-weighted basis, ensuring that only high-stake, trusted neurons can influence consensus. + +### Permit Calculation Algorithm + +Validator permits are calculated every epoch using the following process: + +1. **Stake Filtering**: Only neurons with sufficient stake (minimum 1000 stake weight) are considered +2. **Top-K Selection**: The top K neurons by stake weight are awarded validator permits (typically top 64) +3. **Dynamic Updates**: Permits are recalculated every epoch based on current stake distribution + +### Access Control and Security + +Validator permits control several critical network functions: + +- **Weight Setting**: Only permitted neurons can set non-self weights +- **Consensus Participation**: Only permitted neurons contribute to Yuma Consensus +- **Bond Management**: Neurons retain bonds only if they keep validator permits +- **Active Stake**: Only permitted neurons contribute to active stake calculations + +### Permit Requirements + +To obtain a validator permit, a neuron must meet these criteria: + +- **Minimum Stake**: At least 1000 stake weight (α + 0.18 × τ) +- **Top K Ranking**: Be among the top K neurons by stake weight +- **Active Status**: Maintain active participation in the subnet + +### Permit Lifecycle and Bond Management + +When validator permits are lost, associated bonds are deleted. This ensures that only currently qualified validators can influence consensus. + +### Implementation Details + +For implementation details of how validator permits are calculated, managed, and cleaned up in the codebase, see the [Validator Permit Management section](../navigating-subtensor/epoch.md#validator-permit-management) in the Epoch Implementation documentation. + +### Code References + +- Validator permit calculation: [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:520-537`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L520-537) +- Top-K selection algorithm: [`subtensor/pallets/subtensor/src/epoch/math.rs:250-263`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/math.rs#L250-263) +- Bond cleanup logic: [`subtensor/pallets/subtensor/src/epoch/run_epoch.rs:903-921`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/epoch/run_epoch.rs#L903-921) +- Access control: [`subtensor/pallets/subtensor/src/subnets/weights.rs:745-748`](https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/weights.rs#L745-748) + ## Inspecting UIDs After you obtain a UID slot, you can view the status of your registered wallet by running: @@ -151,28 +210,28 @@ btcli wallet overview --netuid After providing your wallet name at the prompt, you will see output like: -| Parameter | Value | Description | -| :---------- | :----------------- | :------------------------------------------------------------------------- | -| COLDKEY | my_coldkey | The name of the coldkey associated with your slot. | -| HOTKEY | my_first_hotkey | The name of the hotkey associated with your slot. | -| UID | 5 | The index of the uid out of available uids. | -| ACTIVE | True | Whether or not the uid is considered active. | -| STAKE(τ) | 71.296 | The amount of stake in this wallet. | -| RANK | 0.0629 | This miner's absolute ranking according to validators on the network. | -| TRUST | 0.2629 | This miner's trust as a proportion of validators on the network. | -| CONSENSUS | 0.89 | This validator's aggregate consensus score. | -| INCENTIVE | 0.029 | This miner's incentive, TAO emission, is attained via mining. | -| DIVIDENDS | 0.001 | This validator's dividends, TAO emission, are attained via validating. | -| EMISSION | 29_340_153 | This miner's total emission in RAO (10^(-9) TAO) per block. | -| VTRUST | 0.96936 | This validator's trust score as a validator. | -| VPERMIT | \* | Whether this miner is considered active for validating on this subnetwork. | -| UPDATED | 43 | Blocks since this miner set weights on the chain. | -| AXON | 131.186.56.85:8091 | The entrypoint advertised by this miner on the bittensor blockchain. | -| HOTKEY_SS58 | 5F4tQyWr... | The ss58-encoded address of the miner's hotkey. | +| Parameter | Example value | Description | +| :---------- | :----------------- | :------------------------------------------------------------------------------------- | +| COLDKEY | my_coldkey | The name of the coldkey associated with your slot. | +| HOTKEY | my_first_hotkey | The name of the hotkey associated with your slot. | +| UID | 5 | Unique identifier of the neuron. | +| ACTIVE | True | Whether or not the uid is considered active. | +| STAKE(τ) | 71.296 | The amount of stake in this wallet. | +| RANK | 0.0629 | This miner's absolute ranking according to validators on the network. | +| TRUST | 0.2629 | This miner's trust score as a proportion of validators on the network. | +| CONSENSUS | 0.89 | The consensus score of the neuron. | +| INCENTIVE | 0.029 | Thencentive score representing the miner's incentive alignment. | +| DIVIDENDS | 0.001 | The dividends earned by the neuron for validating on the subnet. | +| EMISSION | 29_340_153 | The emission in RAO (p) received by the neuron. | +| VTRUST | 0.96936 | The validator trust score indicating the network's trust in the neuron as a validator. | +| VPERMIT | \* | Whether this neuron is considered eligible for validating on this subnetwork. | +| UPDATED | 43 | Blocks since the neuron set weights on the chain. | +| AXON | 131.186.56.85:8091 | The entrypoint advertised by this miner on the bittensor blockchain. | +| HOTKEY_SS58 | 5F4tQyWr... | The ss58-encoded address of the miner's hotkey. | ### Meaning of ACTIVE -In the above table, the `ACTIVE` row applies only to UIDs that are subnet validators. It shows whether the UID is actively setting weights within the [`activity_cutoff`](../subnets/subnet-hyperparameters#activity_cutoff) window. If the UID has not set weights on the blockchain for the `activity_cutoff` duration, then the Yuma Consensus will consider this subnet validator offline, i.e., turned off (`False`). +In the above table, the `ACTIVE` row applies only to UIDs that are subnet validators. It shows whether the UID is actively setting weights within the [`activity_cutoff`](../subnets/subnet-hyperparameters#activitycutoff) window. If the UID has not set weights on the blockchain for the `activity_cutoff` duration, then the Yuma Consensus will consider this subnet validator offline, i.e., turned off (`False`). ## Checking the registration status diff --git a/docs/validators/validators-btcli-guide.md b/docs/validators/validators-btcli-guide.md index 269ba0380b..c100c9207c 100644 --- a/docs/validators/validators-btcli-guide.md +++ b/docs/validators/validators-btcli-guide.md @@ -6,27 +6,33 @@ title: "Validator's Guide to `BTCLI`" Validators evaluate miner performance, and post their evaluations to the blockchain. This page discusses considerations specific to validators when using `btcli`. -For general coverage of `btcli` permissions and requirements, see: [Bittensor CLI: Permissions Guide](../btcli-permissions) +:::note Transaction Fees +Certain validator operations incur transaction fees. See [Transaction Fees in Bittensor](../learn/fees.md) for details. +::: + +For general coverage of `btcli` permissions and requirements, see: [Bittensor CLI: Permissions Guide](../btcli/btcli-permissions) -See also: [Coldkey and Hotkey Workstation Security](../getting-started/coldkey-hotkey-security). +See also: [Coldkey and Hotkey Workstation Security](../keys/coldkey-hotkey-security). :::tip tips It is highly recommended to use a unique hotkey per subnet. -Note that hotkeys are not encrypted by default, but can be password [optionally encrypted](../working-with-keys#encrypting-the-hotkey). +Note that hotkeys are not encrypted by default, but can be password [optionally encrypted](../keys/working-with-keys#encrypting-the-hotkey). ::: ## Requirements for validator functions ### Unpermissioned workstation (public keys only): + - Check balances - Monitor emissions and other metagraph info - Check subnet alpha prices across Bittensor ### Coldkey workstation: + - Create/import coldkey - Manage TAO and alpha stake -- Create and register a hotkey on a secure coldkey workstation then transfer the hotkey file or mnemonic to the validator workstation: `btcli wallet new-hotkey` , `btcli wallet regen-hotkey` +- Create and register a hotkey on a secure coldkey workstation then transfer the hotkey file or mnemonic to the validator workstation: `btcli wallet new-hotkey` , `btcli wallet regen-hotkey` - Transfer/rotate TAO and alpha stake in case of key compromise - Rotate hotkeys in case of compromise - Register a hotkey on a subnet with `btcli subnets register`, `btcli subnets pow-register` @@ -36,9 +42,9 @@ Note that hotkeys are not encrypted by default, but can be password [optionally These require a hotkey with an active validator permit on the subnet. Run in a live environment (the validator node), which is a hotkey workstation. -- `btcli weights reveal`, `btcli weights commit` -- `btcli wt reveal`, `btcli wt commit` -- `btcli weight reveal`, `btcli weight commit` +- `btcli weights reveal`, `btcli weights commit` +- `btcli wt reveal`, `btcli wt commit` +- `btcli weight reveal`, `btcli weight commit` ### Weight-setting requirements @@ -48,5 +54,4 @@ To set weights, a validator must meet several requirements. See [Requirements fo If you suspect your coldkey may have been leaked, you can request to swap it out of your wallet, using an extrinsic blockchain transaction. This operation has a 5 day waiting period, during which your coldkey will be locked. The cost of this coldkey swap transaction is 0.1 TAO. -See [Rotate/Swap your Coldkey](../subnets/schedule-coldkey-swap) - +See [Rotate/Swap your Coldkey](../keys/schedule-coldkey-swap) diff --git a/docusaurus.config.js b/docusaurus.config.js index 477c973ae2..35fb3711f2 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -10,23 +10,23 @@ const darkTheme = themes.dracula; // KaTex stuff // const math = require("remark-math"); // const katex = require("rehype-katex"); -import remarkMath from 'remark-math'; -import rehypeKatex from 'rehype-katex'; - +import remarkMath from "remark-math"; +import rehypeKatex from "rehype-katex"; /** @type {import('@docusaurus/types').Config} */ const config = { title: "Bittensor", tagline: "Developer Documentation", favicon: "img/favicon.ico", + trailingSlash: false, // Set the production url of your site here - url: "https://docs.bittensor.com", + url: "https://docs.learnbittensor.org", // Set the // pathname under which your site is served // For GitHub pages deployment, it is often '//' baseUrl: "/", // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: "opentensor", // Usually your GitHub org/user name. + organizationName: "latent-to", // Usually your GitHub org/user name. projectName: "developer-docs", // Usually your repo name. onBrokenLinks: "throw", onBrokenMarkdownLinks: "throw", @@ -37,7 +37,7 @@ const config = { customFields: { enableIssueLinks: true, // Set to true to enable issue links enableEditUrlLinks: true, // Set to true to enable edit url links - issueBaseUrl: "https://github.com/opentensor/developer-docs/issues", + issueBaseUrl: "https://github.com/latent-to/developer-docs/issues", enableFeedback: false, // Set to false to disable feedback }, @@ -59,7 +59,7 @@ const config = { sidebarCollapsible: true, showLastUpdateTime: true, docItemComponent: "@theme/DocItem", - editUrl: "https://github.com/opentensor/developer-docs/blob/main/", + editUrl: "https://github.com/latent-to/developer-docs/blob/main/", }, theme: { customCss: require.resolve("./src/css/custom.css"), @@ -73,13 +73,13 @@ const config = { "@docusaurus/plugin-client-redirects", { redirects: [ - { - to: "/btcli", - from: "/reference/btcli", + { + "to": "/subnets/understanding-multiple-mech-subnets", + "from": "/subnets/understanding-sub-subnets" }, - { - to: "/staking-and-delegation/delegation", - from: "/delegation", + { + to: "/liquidity-positions/", + from: "/liquidity-provider", }, { to: "/staking-and-delegation/staking-polkadot-js", @@ -91,39 +91,127 @@ const config = { }, { from: "/subnets/register-validate-mine", - to: "validators/index" + to: "/validators", }, { - from: "/recycled-tao", - to: "/glossary" + to: "/keys/schedule-coldkey-swap", + from: "/subnets/schedule-coldkey-swap", }, { - to: "/subnets/walkthrough-prompting", - from: "/subnets/code-walkthrough-text-prompting", + to: "/sdk/bt-api-ref", + from: "/reference/bittensor-api-ref", }, { - to: "/subtensor-nodes", - from: "/getting-started/running-a-public-subtensor", + to: "/errors", + from: "/subtensor-nodes/subtensor-error-messages", }, { - to: "/", - from: "/subnet-pages", + from: "/glossary", + to: "/resources/glossary", }, { - to: "/subnets/schedule-coldkey-swap", - from: "/schedule-key-swap", + from: "/bittensor-rel-notes", + to: "/resources/bittensor-rel-notes", }, { - to: "/subnets/schedule-coldkey-swap", - from: "/subnets/schedule-key-swap", + from: "/questions-and-answers", + to: "/resources/questions-and-answers", }, - { - to: "/bt-api-ref", - from: "/reference/bittensor-api-ref", + { + from: "/emissions", + to: "/learn/emissions", }, { - to: "/errors", - from: "/subtensor-nodes/subtensor-error-messages", + from: "/yuma-consensus", + to: "/learn/yuma-consensus", + }, + { + from: "/subnets/yc3-blog", + to: "/learn/yc3-blog", + }, + { + from: "/fees", + to: "/learn/fees", + }, + { + from: "/community-links", + to: "/resources/community-links", + }, + { + from: "/subnets/yuma3-migration-guide", + to: "/learn/yuma3-migration-guide", + }, + { + from: "/subnets/child-hotkeys", + to: "/validators/child-hotkeys", + }, + { + from: "/btcli", + to: "/btcli", + }, + { + from: "/btcli-permissions", + to: "/btcli/btcli-permissions", + }, + { + from: "/migration_guide", + to: "/sdk/migration-guide", + }, + { + from: "/bt-api-ref", + to: "/sdk/bt-api-ref", + }, + { + from: "/getting-started/wallets", + to: "/keys/wallets", + }, + { + from: "/getting-started/coldkey-hotkey-security", + to: "/keys/coldkey-hotkey-security", + }, + { + from: "/working-with-keys", + to: "/keys/working-with-keys", + }, + { + from: "/tools", + to: "/concepts/tools", + }, + { + from: "/bittensor-networks", + to: "/concepts/bittensor-networks", + }, + { + from: "/commit-reveal", + to: "/concepts/commit-reveal", + }, + { + from: "/consensus-based-weights", + to: "/concepts/consensus-based-weights", + }, + { + from: "/bt-logging-levels", + to: "/concepts/bt-logging-levels", + }, + { + from: "/utilities", + to: "/resources/utilities", + }, + { + from: "/governance", + to: "/governance", + }, + { + from: "/senate", + to: "/governance/senate", + }, + { + from: "/errors-and-troubleshooting", + to: "/errors/troubleshooting", + }, + { + from: "/media-assets", + to: "/resources/media-assets", }, ], }, @@ -141,7 +229,6 @@ const config = { ], // clientModules: ["/static/feedbug-widjet.js"], - stylesheets: [ { href: "https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css", @@ -151,7 +238,7 @@ const config = { crossorigin: "anonymous", }, { - href: "https://unpkg.com/@antonz/codapi@0.19.10/dist/snippet.css", + href: "https://unpkg.com/@antonz/codapi@0.19.10/dist/snippet.css", }, ], themeConfig: @@ -159,12 +246,21 @@ const config = { ({ // Replace with your project's social card image: "img/bittensor-dev-docs-social-card.png", + announcementBar: { + id: "package_source", + content: + " ⚠️ For security, only use links and commands directly from our docs or official release announcements to avoid malicious lookalikes.", + backgroundColor: "#FFF4E5", + textColor: "#4A2F00", + isCloseable: true, + }, docs: { sidebar: { autoCollapseCategories: true, hideable: false, }, }, + // announcementBar: { // id: 'support_us', // content: @@ -179,7 +275,7 @@ const config = { alt: "Bittensor", src: "img/logo.svg", srcDark: "img/logo-dark-mode.svg", - href: "https://bittensor.com", + href: "https://docs.learnbittensor.org", style: { objectFit: "contain", width: 21, @@ -188,25 +284,25 @@ const config = { items: [ { position: "left", - label: "What is Bittensor?", - to: "learn/introduction", + label: "Announcements", + to: "learn/announcements", }, { position: "left", - label: "SubtensorAPI", - to: "sdk/subtensor-api", + label: "Bittensor SDKv10 Migration Guide", + to: "sdk/migration-guide", }, { position: "left", - label: "Bittensor SDK Reference", - to: "bt-api-ref", + label: "What is Bittensor?", + to: "learn/introduction", }, { position: "left", - label: "BTCLI Live Coding Playground", - to: "btcli/btcli-playground", + label: "Bittensor SDK Reference", + to: "sdk/bt-api-ref", }, - + { position: "left", label: "EVM on Bittensor", @@ -218,12 +314,12 @@ const config = { className: "custom_algolia", }, { - to: "bittensor-rel-notes", + to: "resources/bittensor-rel-notes", label: "Releases", position: "left", }, { - href: "https://github.com/opentensor/developer-docs", + href: "https://github.com/latent-to/developer-docs", label: "Docs GitHub", position: "right", }, @@ -236,20 +332,26 @@ const config = { additionalLanguages: ["bash", "python", "diff", "json", "yaml"], }, algolia: { - appId: "B07G29NY9F", - apiKey: "d23c920e8a9bdae899572be3c8494696", - indexName: "new--alpha", + appId: "UXNFOAH677", + apiKey: "72af66272aba6bd27e76ac6f7eec0068", + indexName: "learnbittensor", contextualSearch: true, insights: true, debug: false, + searchPagePath: "search", + // // Optional: Replace parts of the item URLs from Algolia. Useful when using the same search index for multiple deployments using a different baseUrl. You can use regexp or string in the `from` param. For example: localhost:3000 vs myCompany.com/docs + // replaceSearchResultPathname: { + // from: "/docs/", // or as RegExp: /\/docs\// + // to: "/", + // }, }, footer: { copyright: `
- © ${new Date().getFullYear()} BittensorLatent Holdings, all rights reserved. + © ${new Date().getFullYear()} LearnBittensorLatent Holdings, all rights reserved. contact the docs team
- + logo `, diff --git a/llms.txt b/llms.txt new file mode 100644 index 0000000000..032b5a0b82 --- /dev/null +++ b/llms.txt @@ -0,0 +1,140 @@ +# Bittensor Documentation Resources + +## Official Documentation +The primary sources for Bittensor documentation and learning resources. +- **Main Documentation**: https://docs.bittensor.com - Comprehensive technical documentation covering all aspects of Bittensor +- **Learn Bittensor**: https://learnbittensor.org - User-friendly explanations and tutorials for beginners + +## Quick Reference +- **FAQ**: https://docs.bittensor.com/questions-and-answers - Frequently asked questions +- **Glossary**: https://docs.bittensor.com/glossary - Comprehensive terminology reference +- **Release Notes**: https://docs.bittensor.com/bittensor-rel-notes - Version release information + +## Core Concepts +### Introduction +- **Introduction to Bittensor**: https://docs.bittensor.com/learn/introduction +- **Learn Bittensor Introduction**: https://learnbittensor.org/explore/article/introduction-to-bittensor + +### Subnets +- **Understanding Subnets**: https://docs.bittensor.com/subnets/understanding-subnets +- **Creating Subnets**: https://docs.bittensor.com/subnets/create-a-subnet +- **Subnet Management**: + - Subnet Creators Guide: https://docs.bittensor.com/subnets/subnet-creators-btcli-guide + - Subnet Hyperparameters: https://docs.bittensor.com/subnets/subnet-hyperparameters + - Working with Subnets: https://docs.bittensor.com/subnets/working-with-subnets + - Walkthrough of Example Subnet: https://docs.bittensor.com/subnets/walkthrough-prompting + +### Consensus and Emissions +The mechanisms that power Bittensor's incentive system and reward distribution. +- **Yuma Consensus**: https://docs.bittensor.com/yuma-consensus - Technical details of Bittensor's consensus mechanism +- **Emissions**: https://docs.bittensor.com/emissions - How TAO and alpha tokens are distributed in the network + +### Dynamic TAO +- **Dynamic TAO Guide**: https://docs.bittensor.com/dynamic-tao/dtao-guide +- **Dynamic TAO FAQ**: https://docs.bittensor.com/dynamic-tao/dtao-faq +- **SDK Cheat Sheet**: https://docs.bittensor.com/dynamic-tao/sdk-cheat-sheet + +## Network Participants +### Miners +Participants who provide AI services to the network. +- **Miner Documentation**: https://docs.bittensor.com/miners/ - Complete guide to mining on Bittensor +- **Miner Guide**: https://docs.bittensor.com/miners/miners-btcli-guide - Command-line interface guide for miners +- **Learn Bittensor Miner Concept**: https://learnbittensor.org/explore/concept/miner - Simplified explanation of mining + +### Validators +Network participants who verify and rank miner performance. +- **Validator Documentation**: https://docs.bittensor.com/validators/ - Comprehensive validator guide +- **Validator Guide**: https://docs.bittensor.com/validators/validators-btcli-guide - CLI operations for validators +- **Child Hotkeys**: https://docs.bittensor.com/validators/subnets/child-hotkeys - Managing multiple validator instances +- **Learn Bittensor Validator Concept**: https://learnbittensor.org/explore/concept/validator - Beginner's guide to validation + +### Staking and Delegation +- **Staking/Delegation Overview**: https://docs.bittensor.com/staking-and-delegation/delegation +- **Staking Guides**: + - BTCLI Guide: https://docs.bittensor.com/staking-and-delegation/stakers-btcli-guide + - Managing Stake with BTCLI: https://docs.bittensor.com/staking-and-delegation/managing-stake-btcli + - Managing Stake with SDK: https://docs.bittensor.com/staking-and-delegation/managing-stake-sdk + - Polkadot.js Guide: https://docs.bittensor.com/staking-and-delegation/staking-polkadot-js + - Ledger Hardware Wallet: https://docs.bittensor.com/staking-and-delegation/using-ledger-hw-wallet + +## Development Tools +Essential tools for building and interacting with Bittensor. + +### BTCLI (Command Line Interface) +The primary command-line tool for Bittensor operations. +- **Overview**: https://docs.bittensor.com/btcli/overview - Introduction to BTCLI +- **Installation**: https://docs.bittensor.com/getting-started/install-btcli - Setting up BTCLI +- **Playground**: https://docs.bittensor.com/btcli/btcli-playground - Interactive BTCLI learning environment +- **Permissions**: https://docs.bittensor.com/btcli-permissions - Understanding BTCLI access levels +- **Full Reference**: https://docs.bittensor.com/btcli - Complete command reference + +### Bittensor Python SDK +- **Installation**: https://docs.bittensor.com/getting-started/installation +- **Wallet SDK Installation**: https://docs.bittensor.com/getting-started/install-wallet-sdk +- **SDK Documentation**: + - Async Subtensor: https://docs.bittensor.com/python-api/autoapi/bittensor/core/async_subtensor/index.html + - Subtensor: https://docs.bittensor.com/python-api/autoapi/bittensor/core/subtensor/index.html + - Metagraph API: https://docs.bittensor.com/python-api/html/autoapi/bittensor/metagraph/index.html + - Bittensor Wallet: https://docs.bittensor.com/btwallet-api/html/autoapi/btwallet/wallet/index.html +- **Migration Guide**: https://docs.bittensor.com/migration_guide +- **Subtensor Connections**: https://docs.bittensor.com/sdk/managing-subtensor-connections + +## Security +### Wallets and Keys +- **Wallet Basics**: https://docs.bittensor.com/getting-started/wallets +- **Seed Phrase Security**: https://docs.bittensor.com/keys/handle-seed-phrase +- **Coldkey/Hotkey Security**: https://docs.bittensor.com/getting-started/coldkey-hotkey-security +- **Working with Keys**: https://docs.bittensor.com/working-with-keys +- **Multisig Security**: https://docs.bittensor.com/keys/multisig +- **Coldkey Rotation**: https://docs.bittensor.com/subnets/schedule-coldkey-swap + +## Network Environments +### Endpoints +- **Mainnet**: wss://entrypoint-finney.opentensor.ai:443 +- **Testnet**: wss://test.finney.opentensor.ai:443 +- **Devnet**: wss://dev.chain.opentensor.ai:443 + +## Advanced Topics +### Local Development +- **Local Subtensor Deployment**: https://docs.bittensor.com/local-build/deploy + +### Subtensor Nodes +- **Node Basics**: https://docs.bittensor.com/subtensor-nodes/ +- **Node Requirements**: https://docs.bittensor.com/subtensor-nodes/subtensor-node-requirements +- **Source Installation**: https://docs.bittensor.com/subtensor-nodes/using-source +- **Docker Installation**: https://docs.bittensor.com/subtensor-nodes/using-docker +- **Rate Limits**: https://docs.bittensor.com/subtensor-nodes/subtensor-rate-limits +- **Storage Queries**: https://docs.bittensor.com/subtensor-nodes/subtensor-storage-query-examples +- **Error Messages**: https://docs.bittensor.com/subtensor-nodes/subtensor-error-messages + +### EVM Integration +- **EVM on Bittensor Overview**: https://docs.bittensor.com/evm-tutorials/ +- **EVM on Subtensor**: https://docs.bittensor.com/evm-tutorials/evm-on-subtensor +- **Installation**: https://docs.bittensor.com/evm-tutorials/install +- **Setup**: + - Hardhat Config: https://docs.bittensor.com/evm-tutorials/hardhat-config-for-subtensor-evm + - Testnet: https://docs.bittensor.com/evm-tutorials/evm-testnet-with-metamask-wallet + - Localnet: https://docs.bittensor.com/evm-tutorials/evm-localnet-with-metamask-wallet + - Mainnet: https://docs.bittensor.com/evm-tutorials/evm-mainnet-with-metamask-wallet +- **Precompiles**: + - Metamask to SS58: https://docs.bittensor.com/evm-tutorials/transfer-from-metamask-to-ss58 + - Between H160 Accounts: https://docs.bittensor.com/evm-tutorials/transfer-between-two-h160-accounts + - Staking Precompile: https://docs.bittensor.com/evm-tutorials/staking-precompile + - ED25519 Verify: https://docs.bittensor.com/evm-tutorials/ed25519-verify-precompile + +### Governance +- **Overview**: https://docs.bittensor.com/governance +- **Senate**: https://docs.bittensor.com/senate +- **Senator Guide**: https://docs.bittensor.com/governance/senators-btcli-guide + +## Releases and Downloads +### Bittensor +- **PyPI**: https://pypi.org/project/bittensor/ +- **GitHub**: https://github.com/opentensor/bittensor/releases + +### BTCLI +- **PyPI**: https://pypi.org/project/bittensor-cli/ +- **GitHub**: https://github.com/opentensor/btcli/releases + +### Subtensor +- **GitHub**: https://github.com/opentensor/subtensor/releases diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 599ad73957..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,17442 +0,0 @@ -{ - "name": "bittensor-docs", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "bittensor-docs", - "version": "0.0.0", - "dependencies": { - "@docusaurus/core": "^3.4.0", - "@docusaurus/plugin-client-redirects": "^3.4.0", - "@docusaurus/preset-classic": "^3.4.0", - "@gracefullight/docusaurus-plugin-vercel-analytics": "^1.0.0", - "@mdx-js/react": "^3.0.0", - "@vercel/analytics": "^1.1.2", - "clsx": "^1.2.1", - "hast-util-is-element": "1.1.0", - "prism-react-renderer": "^2.1.0", - "punycode": "^2.3.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-icons": "^4.12.0", - "rehype-katex": "^7.0.1", - "remark-definition-list": "^2.0.0", - "remark-math": "^6.0.0", - "zwitch": "^2.0.4" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "^3.3.2", - "@docusaurus/tsconfig": "^3.3.2", - "@docusaurus/types": "^3.3.2", - "typescript": "~5.2.2" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", - "license": "MIT", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.22.1.tgz", - "integrity": "sha512-Sw6IAmOCvvP6QNgY9j+Hv09mvkvEIDKjYW8ow0UDDAxSXy664RBNQk3i/0nt7gvceOJ6jGmOTimaZoY1THmU7g==", - "license": "MIT", - "dependencies": { - "@algolia/cache-common": "4.22.1" - } - }, - "node_modules/@algolia/cache-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.22.1.tgz", - "integrity": "sha512-TJMBKqZNKYB9TptRRjSUtevJeQVXRmg6rk9qgFKWvOy8jhCPdyNZV1nB3SKGufzvTVbomAukFR8guu/8NRKBTA==", - "license": "MIT" - }, - "node_modules/@algolia/cache-in-memory": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.22.1.tgz", - "integrity": "sha512-ve+6Ac2LhwpufuWavM/aHjLoNz/Z/sYSgNIXsinGofWOysPilQZPUetqLj8vbvi+DHZZaYSEP9H5SRVXnpsNNw==", - "license": "MIT", - "dependencies": { - "@algolia/cache-common": "4.22.1" - } - }, - "node_modules/@algolia/client-account": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.22.1.tgz", - "integrity": "sha512-k8m+oegM2zlns/TwZyi4YgCtyToackkOpE+xCaKCYfBfDtdGOaVZCM5YvGPtK+HGaJMIN/DoTL8asbM3NzHonw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/transporter": "4.22.1" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.22.1.tgz", - "integrity": "sha512-1ssi9pyxyQNN4a7Ji9R50nSdISIumMFDwKNuwZipB6TkauJ8J7ha/uO60sPJFqQyqvvI+px7RSNRQT3Zrvzieg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" - } - }, - "node_modules/@algolia/client-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.22.1.tgz", - "integrity": "sha512-IvaL5v9mZtm4k4QHbBGDmU3wa/mKokmqNBqPj0K7lcR8ZDKzUorhcGp/u8PkPC/e0zoHSTvRh7TRkGX3Lm7iOQ==", - "license": "MIT", - "dependencies": { - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.22.1.tgz", - "integrity": "sha512-sl+/klQJ93+4yaqZ7ezOttMQ/nczly/3GmgZXJ1xmoewP5jmdP/X/nV5U7EHHH3hCUEHeN7X1nsIhGPVt9E1cQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" - } - }, - "node_modules/@algolia/client-search": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.22.1.tgz", - "integrity": "sha512-yb05NA4tNaOgx3+rOxAmFztgMTtGBi97X7PC3jyNeGiwkAjOZc2QrdZBYyIdcDLoI09N0gjtpClcackoTN0gPA==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" - } - }, - "node_modules/@algolia/events": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", - "license": "MIT" - }, - "node_modules/@algolia/logger-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.22.1.tgz", - "integrity": "sha512-OnTFymd2odHSO39r4DSWRFETkBufnY2iGUZNrMXpIhF5cmFE8pGoINNPzwg02QLBlGSaLqdKy0bM8S0GyqPLBg==", - "license": "MIT" - }, - "node_modules/@algolia/logger-console": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.22.1.tgz", - "integrity": "sha512-O99rcqpVPKN1RlpgD6H3khUWylU24OXlzkavUAMy6QZd1776QAcauE3oP8CmD43nbaTjBexZj2nGsBH9Tc0FVA==", - "license": "MIT", - "dependencies": { - "@algolia/logger-common": "4.22.1" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.22.1.tgz", - "integrity": "sha512-dtQGYIg6MteqT1Uay3J/0NDqD+UciHy3QgRbk7bNddOJu+p3hzjTRYESqEnoX/DpEkaNYdRHUKNylsqMpgwaEw==", - "license": "MIT", - "dependencies": { - "@algolia/requester-common": "4.22.1" - } - }, - "node_modules/@algolia/requester-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.22.1.tgz", - "integrity": "sha512-dgvhSAtg2MJnR+BxrIFqlLtkLlVVhas9HgYKMk2Uxiy5m6/8HZBL40JVAMb2LovoPFs9I/EWIoFVjOrFwzn5Qg==", - "license": "MIT" - }, - "node_modules/@algolia/requester-node-http": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.22.1.tgz", - "integrity": "sha512-JfmZ3MVFQkAU+zug8H3s8rZ6h0ahHZL/SpMaSasTCGYR5EEJsCc8SI5UZ6raPN2tjxa5bxS13BRpGSBUens7EA==", - "license": "MIT", - "dependencies": { - "@algolia/requester-common": "4.22.1" - } - }, - "node_modules/@algolia/transporter": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.22.1.tgz", - "integrity": "sha512-kzWgc2c9IdxMa3YqA6TN0NW5VrKYYW/BELIn7vnLyn+U/RFdZ4lxxt9/8yq3DKV5snvoDzzO4ClyejZRdV3lMQ==", - "license": "MIT", - "dependencies": { - "@algolia/cache-common": "4.22.1", - "@algolia/logger-common": "4.22.1", - "@algolia/requester-common": "4.22.1" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", - "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.0", - "@babel/generator": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.0", - "@babel/parser": "^7.26.0", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.26.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", - "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.26.3", - "@babel/types": "^7.26.3", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.10", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz", - "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", - "license": "MIT", - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", - "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.26.3" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", - "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", - "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", - "license": "MIT", - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz", - "integrity": "sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", - "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/types": "^7.23.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", - "license": "MIT", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", - "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.9.tgz", - "integrity": "sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", - "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz", - "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.9", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.9", - "@babel/plugin-transform-modules-umd": "^7.23.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.23.4", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", - "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-transform-react-display-name": "^7.23.3", - "@babel/plugin-transform-react-jsx": "^7.22.15", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", - "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-typescript": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "license": "MIT" - }, - "node_modules/@babel/runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", - "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.9.tgz", - "integrity": "sha512-oeOFTrYWdWXCvXGB5orvMTJ6gCZ9I6FBjR+M38iKNXCsPxr4xT0RTdg5uz1H7QP8pp74IzPtwritEr+JscqHXQ==", - "license": "MIT", - "dependencies": { - "core-js-pure": "^3.30.2", - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.26.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", - "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.3", - "@babel/parser": "^7.26.3", - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.3", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", - "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz", - "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==", - "license": "MIT" - }, - "node_modules/@docsearch/react": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz", - "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.5.2", - "algoliasearch": "^4.19.1" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 19.0.0", - "react": ">= 16.8.0 < 19.0.0", - "react-dom": ">= 16.8.0 < 19.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@docusaurus/core": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.4.0.tgz", - "integrity": "sha512-g+0wwmN2UJsBqy2fQRQ6fhXruoEa62JDeEa5d8IdTJlMoaDaEDfHh7WjwGRn4opuTQWpjAwP/fbcgyHKlE+64w==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.23.3", - "@babel/generator": "^7.23.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/preset-react": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "@babel/runtime": "^7.22.6", - "@babel/runtime-corejs3": "^7.22.6", - "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "autoprefixer": "^10.4.14", - "babel-loader": "^9.1.3", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.2", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.31.1", - "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^5.0.1", - "cssnano": "^6.1.2", - "del": "^6.1.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "eval": "^0.1.8", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "html-minifier-terser": "^7.2.0", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.5.3", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.7.6", - "p-map": "^4.0.0", - "postcss": "^8.4.26", - "postcss-loader": "^7.3.3", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "rtl-detect": "^1.0.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.5", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "url-loader": "^4.1.1", - "webpack": "^5.88.1", - "webpack-bundle-analyzer": "^4.9.0", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.9.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/core/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@docusaurus/core/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@docusaurus/core/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/@docusaurus/cssnano-preset": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.4.0.tgz", - "integrity": "sha512-qwLFSz6v/pZHy/UP32IrprmH5ORce86BGtN0eBtG75PpzQJAzp9gefspox+s8IEOr0oZKuQ/nhzZ3xwyc3jYJQ==", - "license": "MIT", - "dependencies": { - "cssnano-preset-advanced": "^6.1.2", - "postcss": "^8.4.38", - "postcss-sort-media-queries": "^5.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/cssnano-preset/node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/@docusaurus/cssnano-preset/node_modules/cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "license": "MIT", - "dependencies": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/@docusaurus/cssnano-preset/node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/@docusaurus/cssnano-preset/node_modules/postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/@docusaurus/cssnano-preset/node_modules/postcss-merge-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", - "license": "MIT", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/@docusaurus/cssnano-preset/node_modules/postcss-reduce-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/@docusaurus/cssnano-preset/node_modules/postcss-sort-media-queries": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", - "license": "MIT", - "dependencies": { - "sort-css-media-queries": "2.2.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.4.23" - } - }, - "node_modules/@docusaurus/cssnano-preset/node_modules/postcss-zindex": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/@docusaurus/logger": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.4.0.tgz", - "integrity": "sha512-bZwkX+9SJ8lB9kVRkXw+xvHYSMGG4bpYHKGXeXFvyVc79NMeeBSGgzd4TQLHH+DYeOJoCdl8flrFJVxlZ0wo/Q==", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/mdx-loader": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.4.0.tgz", - "integrity": "sha512-kSSbrrk4nTjf4d+wtBA9H+FGauf2gCax89kV8SUSJu3qaTdSIKdWERlngsiHaCFgZ7laTJ8a67UFf+xlFPtuTw==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^1.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/module-type-aliases": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.3.2.tgz", - "integrity": "sha512-b/XB0TBJah5yKb4LYuJT4buFvL0MGAb0+vJDrJtlYMguRtsEBkf2nWl5xP7h4Dlw6ol0hsHrCYzJ50kNIOEclw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@docusaurus/types": "3.3.2", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/module-type-aliases/node_modules/react-helmet-async": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.4.tgz", - "integrity": "sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "invariant": "^2.2.4", - "react-fast-compare": "^3.2.2", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-client-redirects": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.4.0.tgz", - "integrity": "sha512-Pr8kyh/+OsmYCvdZhc60jy/FnrY6flD2TEAhl4rJxeVFxnvvRgEhoaIVX8q9MuJmaQoh6frPk94pjs7/6YgBDQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.4.0.tgz", - "integrity": "sha512-vv6ZAj78ibR5Jh7XBUT4ndIjmlAxkijM3Sx5MAAzC1gyv0vupDQNhzuFg1USQmQVj3P5I6bquk12etPV3LJ+Xw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "cheerio": "^1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "reading-time": "^1.5.0", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.4.0.tgz", - "integrity": "sha512-HkUCZffhBo7ocYheD9oZvMcDloRnGhBMOZRyVcAQRFmZPmNqSyISlXA1tQCIxW+r478fty97XXAGjNYzBjpCsg==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/module-type-aliases": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.4.0.tgz", - "integrity": "sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw==", - "license": "MIT", - "dependencies": { - "@docusaurus/types": "3.4.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/types/node_modules/react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/react-helmet-async": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.4.tgz", - "integrity": "sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ==", - "license": "Apache-2.0", - "dependencies": { - "invariant": "^2.2.4", - "react-fast-compare": "^3.2.2", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.4.0.tgz", - "integrity": "sha512-h2+VN/0JjpR8fIkDEAoadNjfR3oLzB+v1qSXbIAKjQ46JAHx3X22n9nqS+BWSQnTnp1AjkjSvZyJMekmcwxzxg==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-debug": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.4.0.tgz", - "integrity": "sha512-uV7FDUNXGyDSD3PwUaf5YijX91T5/H9SX4ErEcshzwgzWwBtK37nUWPU3ZLJfeTavX3fycTOqk9TglpOLaWkCg==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^1.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-debug/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.4.0.tgz", - "integrity": "sha512-mCArluxEGi3cmYHqsgpGGt3IyLCrFBxPsxNZ56Mpur0xSlInnIHoeLDH7FvVVcPJRPSQ9/MfRqLsainRw+BojA==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.4.0.tgz", - "integrity": "sha512-Dsgg6PLAqzZw5wZ4QjUYc8Z2KqJqXxHxq3vIoyoBWiLEEfigIs7wHR+oiWUQy3Zk9MIk6JTYj7tMoQU0Jm3nqA==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-gtag/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.4.0.tgz", - "integrity": "sha512-O9tX1BTwxIhgXpOLpFDueYA9DWk69WCbDRrjYoMQtFHSkTyE7RhNgyjSPREUWJb9i+YUg3OrsvrBYRl64FCPCQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-tag-manager/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.4.0.tgz", - "integrity": "sha512-+0VDvx9SmNrFNgwPoeoCha+tRoAjopwT0+pYO1xAbyLcewXSemq+eLxEa46Q1/aoOaJQ0qqHELuQM7iS2gp33Q==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-sitemap/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/preset-classic": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.4.0.tgz", - "integrity": "sha512-Ohj6KB7siKqZaQhNJVMBBUzT3Nnp6eTKqO+FXO3qu/n1hJl3YLwVKTWBg28LF7MWrKu46UuYavwMRxud0VyqHg==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/plugin-debug": "3.4.0", - "@docusaurus/plugin-google-analytics": "3.4.0", - "@docusaurus/plugin-google-gtag": "3.4.0", - "@docusaurus/plugin-google-tag-manager": "3.4.0", - "@docusaurus/plugin-sitemap": "3.4.0", - "@docusaurus/theme-classic": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-search-algolia": "3.4.0", - "@docusaurus/types": "3.4.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/preset-classic/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-classic": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.4.0.tgz", - "integrity": "sha512-0IPtmxsBYv2adr1GnZRdMkEQt1YW6tpzrUPj02YxNpvJ5+ju4E13J5tB4nfdaen/tfR1hmpSPlTFPvTf4kwy8Q==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.4.0", - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-translations": "3.4.0", - "@docusaurus/types": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.43", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.4.26", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/module-type-aliases": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.4.0.tgz", - "integrity": "sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw==", - "license": "MIT", - "dependencies": { - "@docusaurus/types": "3.4.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/types/node_modules/react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/react-helmet-async": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.4.tgz", - "integrity": "sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ==", - "license": "Apache-2.0", - "dependencies": { - "invariant": "^2.2.4", - "react-fast-compare": "^3.2.2", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@docusaurus/theme-common": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.4.0.tgz", - "integrity": "sha512-0A27alXuv7ZdCg28oPE8nH/Iz73/IUejVaCazqu9elS4ypjiLhK3KfzdSQBnL/g7YfHSlymZKdiOHEo8fJ0qMA==", - "license": "MIT", - "dependencies": { - "@docusaurus/mdx-loader": "3.4.0", - "@docusaurus/module-type-aliases": "3.4.0", - "@docusaurus/plugin-content-blog": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/plugin-content-pages": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/module-type-aliases": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.4.0.tgz", - "integrity": "sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw==", - "license": "MIT", - "dependencies": { - "@docusaurus/types": "3.4.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/types": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz", - "integrity": "sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/types/node_modules/react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@docusaurus/theme-common/node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/theme-common/node_modules/react-helmet-async": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.4.tgz", - "integrity": "sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ==", - "license": "Apache-2.0", - "dependencies": { - "invariant": "^2.2.4", - "react-fast-compare": "^3.2.2", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.4.0.tgz", - "integrity": "sha512-aiHFx7OCw4Wck1z6IoShVdUWIjntC8FHCw9c5dR8r3q4Ynh+zkS8y2eFFunN/DL6RXPzpnvKCg3vhLQYJDmT9Q==", - "license": "MIT", - "dependencies": { - "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.4.0", - "@docusaurus/logger": "3.4.0", - "@docusaurus/plugin-content-docs": "3.4.0", - "@docusaurus/theme-common": "3.4.0", - "@docusaurus/theme-translations": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-validation": "3.4.0", - "algoliasearch": "^4.18.0", - "algoliasearch-helper": "^3.13.3", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia/node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/theme-translations": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.4.0.tgz", - "integrity": "sha512-zSxCSpmQCCdQU5Q4CnX/ID8CSUUI3fvmq4hU/GNP/XoAWtXo9SAVnM3TzpU8Gb//H3WCsT8mJcTfyOk3d9ftNg==", - "license": "MIT", - "dependencies": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/tsconfig": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.3.2.tgz", - "integrity": "sha512-2MQXkLoWqgOSiqFojNEq8iPtFBHGQqd1b/SQMoe+v3GgHmk/L6YTTO/hMcHhWb1hTFmbkei++IajSfD3RlZKvw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@docusaurus/types": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.3.2.tgz", - "integrity": "sha512-5p201S7AZhliRxTU7uMKtSsoC8mgPA9bs9b5NQg1IRdRxJfflursXNVsgc3PcMqiUTul/v1s3k3rXXFlRE890w==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/utils": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.4.0.tgz", - "integrity": "sha512-fRwnu3L3nnWaXOgs88BVBmG1yGjcQqZNHG+vInhEa2Sz2oQB+ZjbEMO5Rh9ePFpZ0YDiDUhpaVjwmS+AU2F14g==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "@svgr/webpack": "^8.1.0", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "prompts": "^2.4.2", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/utils-common": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.4.0.tgz", - "integrity": "sha512-NVx54Wr4rCEKsjOH5QEVvxIqVvm+9kh7q8aYTU5WzUU9/Hctd6aTrcZ3G0Id4zYJ+AeaG5K5qHA4CY5Kcm2iyQ==", - "license": "MIT", - "dependencies": { - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/utils-validation": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.4.0.tgz", - "integrity": "sha512-hYQ9fM+AXYVTWxJOT1EuNaRnrR2WGpRdLDQG07O8UOpsvCPWUVOeo26Rbm0JWY2sGLfzAb+tvJ62yF+8F+TV0g==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.4.0", - "@docusaurus/utils": "3.4.0", - "@docusaurus/utils-common": "3.4.0", - "fs-extra": "^11.2.0", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@gracefullight/docusaurus-plugin-vercel-analytics/-/docusaurus-plugin-vercel-analytics-1.0.1.tgz", - "integrity": "sha512-6Xj63GIBadwLhoDVNpRXlEs3ieTetd8ZcNGKIJ8ADT0IjZIvcIW6CZFY5RgGtxuJ4PxFXVU2DDV14M2uXXTvGQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/utils-validation": "^3" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/@docusaurus/logger": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.1.1.tgz", - "integrity": "sha512-BjkNDpQzewcTnST8trx4idSoAla6zZ3w22NqM/UMcFtvYJgmoE4layuTzlfql3VFPNuivvj7BOExa/+21y4X2Q==", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/@docusaurus/utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.1.1.tgz", - "integrity": "sha512-ZJfJa5cJQtRYtqijsPEnAZoduW6sjAQ7ZCWSZavLcV10Fw0Z3gSaPKA/B4micvj2afRZ4gZxT7KfYqe5H8Cetg==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.1.1", - "@svgr/webpack": "^6.5.1", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/@docusaurus/utils-validation": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.1.1.tgz", - "integrity": "sha512-KlY4P9YVDnwL+nExvlIpu79abfEv6ZCHuOX4ZQ+gtip+Wxj0daccdReIWWtqxM/Fb5Cz1nQvUCc7VEtT8IBUAA==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.1.1", - "@docusaurus/utils": "3.1.1", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/@svgr/plugin-svgo": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", - "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "svgo": "^2.8.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/@svgr/webpack": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", - "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.19.6", - "@babel/plugin-transform-react-constant-elements": "^7.18.12", - "@babel/preset-env": "^7.19.4", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@svgr/core": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", - "@svgr/plugin-svgo": "^6.5.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "license": "MIT", - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@gracefullight/docusaurus-plugin-vercel-analytics/node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "license": "MIT", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", - "license": "MIT" - }, - "node_modules/@mdx-js/mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", - "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-to-js": "^2.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@mdx-js/react": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", - "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", - "license": "MIT", - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "license": "MIT", - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "4.2.10" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "license": "ISC" - }, - "node_modules/@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "license": "MIT", - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.24", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", - "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==", - "license": "MIT" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "license": "BSD-3-Clause" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "license": "MIT" - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "node_modules/@slorber/remark-comment/node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@slorber/remark-comment/node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@slorber/remark-comment/node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/@slorber/remark-comment/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", - "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", - "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", - "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", - "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", - "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", - "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", - "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", - "license": "MIT", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", - "@svgr/babel-plugin-remove-jsx-attribute": "*", - "@svgr/babel-plugin-remove-jsx-empty-expression": "*", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.5.1", - "@svgr/babel-plugin-svg-dynamic-title": "^6.5.1", - "@svgr/babel-plugin-svg-em-dimensions": "^6.5.1", - "@svgr/babel-plugin-transform-react-native-svg": "^6.5.1", - "@svgr/babel-plugin-transform-svg-component": "^6.5.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/core": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", - "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/core/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", - "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.0", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", - "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/hast-util-to-babel-ast": "^6.5.1", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "^6.0.0" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz", - "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.24.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz", - "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/helper-plugin-utils": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz", - "integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", - "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz", - "integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==", - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", - "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", - "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", - "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", - "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", - "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", - "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", - "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", - "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", - "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", - "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz", - "integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", - "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz", - "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.4", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-classes": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz", - "integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.24.5", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", - "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/template": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz", - "integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", - "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", - "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", - "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", - "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", - "license": "MIT", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", - "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", - "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", - "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", - "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", - "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", - "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", - "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", - "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", - "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", - "license": "MIT", - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", - "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", - "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", - "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", - "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz", - "integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", - "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", - "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz", - "integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz", - "integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", - "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz", - "integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.5", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", - "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.1.tgz", - "integrity": "sha512-QXp1U9x0R7tkiGB0FOk8o74jhnap0FlZ5gNkRIWdG3eP+SvMFg118e1zaWewDzgABb106QSKpVsD3Wgd8t6ifA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", - "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", - "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", - "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", - "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", - "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", - "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz", - "integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.5.tgz", - "integrity": "sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.5", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-typescript": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", - "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", - "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", - "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", - "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/preset-env": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz", - "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.24.4", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.5", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.4", - "@babel/plugin-transform-classes": "^7.24.5", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.5", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.5", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.5", - "@babel/plugin-transform-parameters": "^7.24.5", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.5", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.5", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@babel/preset-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz", - "integrity": "sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-syntax-jsx": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-typescript": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "license": "MIT", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/webpack/node_modules/@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/webpack/node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@svgr/webpack/node_modules/babel-plugin-polyfill-corejs3/node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/@svgr/webpack/node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "license": "ISC", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "license": "MIT", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", - "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.4.tgz", - "integrity": "sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", - "license": "MIT" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "license": "MIT" - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "license": "MIT" - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "license": "MIT" - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "license": "MIT" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", - "license": "MIT" - }, - "node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdx": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.11.tgz", - "integrity": "sha512-HM5bwOaIQJIQbAYfax35HCKxx7a3KrK3nBtIqJgSOitivTD1y3oW9P3rxY9RkXYPUk7y/AjAohfHKmFpGE79zw==", - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.4.tgz", - "integrity": "sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.11.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", - "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "license": "MIT" - }, - "node_modules/@types/prismjs": { - "version": "1.26.3", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", - "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==", - "license": "MIT" - }, - "node_modules/@types/prop-types": { - "version": "15.7.11", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "license": "MIT" - }, - "node_modules/@types/qs": { - "version": "6.9.11", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "18.2.57", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.57.tgz", - "integrity": "sha512-ZvQsktJgSYrQiMirAN60y4O/LRevIV8hUzSOSNB6gfR3/o3wCBFQx3sPwIYtuDMeiVgsSS3UzCV26tEzgnfvQw==", - "license": "MIT", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-config": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "license": "MIT" - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/send/node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "license": "MIT" - }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "license": "ISC" - }, - "node_modules/@vercel/analytics": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.2.tgz", - "integrity": "sha512-X0rctVWkQV1e5Y300ehVNqpOfSOufo7ieA5PIdna8yX/U7Vjz0GFsGf4qvAhxV02uQ2CVt7GYcrFfddXXK2Y4A==", - "license": "MPL-2.0", - "dependencies": { - "server-only": "^0.0.1" - }, - "peerDependencies": { - "next": ">= 13", - "react": "^18 || ^19" - }, - "peerDependenciesMeta": { - "next": { - "optional": true - }, - "react": { - "optional": true - } - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/algoliasearch": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.22.1.tgz", - "integrity": "sha512-jwydKFQJKIx9kIZ8Jm44SdpigFwRGPESaxZBaHSV0XWN2yBJAOT4mT7ppvlrpA4UGzz92pqFnVKr/kaZXrcreg==", - "license": "MIT", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.22.1", - "@algolia/cache-common": "4.22.1", - "@algolia/cache-in-memory": "4.22.1", - "@algolia/client-account": "4.22.1", - "@algolia/client-analytics": "4.22.1", - "@algolia/client-common": "4.22.1", - "@algolia/client-personalization": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/logger-common": "4.22.1", - "@algolia/logger-console": "4.22.1", - "@algolia/requester-browser-xhr": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/requester-node-http": "4.22.1", - "@algolia/transporter": "4.22.1" - } - }, - "node_modules/algoliasearch-helper": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.16.2.tgz", - "integrity": "sha512-Yl/Gu5Cq4Z5s/AJ0jR37OPI1H3+z7PHz657ibyaXgMOaWvPlZ3OACN13N+7HCLPUlB0BN+8BtmrG/CqTilowBA==", - "license": "MIT", - "dependencies": { - "@algolia/events": "^4.0.1" - }, - "peerDependencies": { - "algoliasearch": ">= 3.1 < 6" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "node_modules/astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", - "license": "MIT", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.22.2", - "caniuse-lite": "^1.0.30001578", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "license": "MIT", - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "license": "MIT", - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", - "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.5.0", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", - "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0", - "core-js-compat": "^3.34.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "license": "MIT" - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/boxen": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^6.2.0", - "chalk": "^4.1.2", - "cli-boxes": "^3.0.0", - "string-width": "^5.0.1", - "type-fest": "^2.5.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "license": "MIT", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request/node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001687", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", - "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cheerio-select/node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "license": "MIT", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/combine-promises": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "license": "ISC" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "license": "MIT", - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "license": "BSD-2-Clause", - "dependencies": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/yeoman/configstore?sponsor=1" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", - "license": "MIT" - }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "license": "MIT", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "license": "MIT", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/core-js": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", - "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", - "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.22.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.0.tgz", - "integrity": "sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "license": "MIT", - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", - "license": "ISC", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-loader": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", - "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.4", - "postcss-modules-scope": "^3.1.1", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-loader/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/css-loader/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/css-loader/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "cssnano": "^6.0.1", - "jest-worker": "^29.4.3", - "postcss": "^8.4.24", - "schema-utils": "^4.0.1", - "serialize-javascript": "^6.0.1" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "lightningcss": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-select/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/css-select/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/css-select/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/css-select/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", - "license": "MIT", - "dependencies": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "license": "MIT", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "license": "BSD-2-Clause", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "license": "MIT", - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "license": "MIT" - }, - "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "license": "MIT", - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "license": "MIT", - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port-alt/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port-alt/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "license": "MIT", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "license": "MIT", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "license": "MIT" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.72", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.72.tgz", - "integrity": "sha512-ZpSAUOZ2Izby7qnZluSrAlGgGQzucmFbN0n64dYzocYxnxV5ufurpj3VgEe4cUp7ir9LmeLxNYo8bVnlM8bQHw==", - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", - "license": "MIT" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/emoticon": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", - "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", - "license": "MIT" - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/estree-util-value-to-estree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", - "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "is-plain-obj": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "url": "https://github.com/eta-dev/eta?sponsor=1" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "dependencies": { - "@types/node": "*", - "require-like": ">= 0.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "license": "MIT" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "license": "MIT", - "dependencies": { - "punycode": "^1.3.2" - } - }, - "node_modules/fast-url-parser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "license": "MIT", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/feed": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "license": "MIT", - "dependencies": { - "xml-js": "^1.6.11" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "license": "MIT", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "license": "MIT", - "engines": { - "node": ">= 14.17" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", - "license": "Unlicense" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "license": "ISC" - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", - "license": "ISC" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" - }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "license": "MIT", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "license": "MIT", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "license": "MIT", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "license": "MIT", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-definition-list": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-definition-list/-/hast-util-definition-list-2.0.0.tgz", - "integrity": "sha512-EnkqD6a7R1fwyC9F5R6fu0ucpcwfkxjiga7/G8J7KU+uuUHVENzmgo/Da68fZBy9SZAkQOAC/8gK3m2BnuutUg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.1", - "@types/mdast": "^4.0.1", - "@types/unist": "^3.0.0", - "hast-util-to-mdast": "^10.1.0", - "mdast-util-definition-list": "^2.0.0", - "mdast-util-phrasing": "^4.0.0" - } - }, - "node_modules/hast-util-embedded": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz", - "integrity": "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-is-element": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-embedded/node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-dom": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", - "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", - "license": "ISC", - "dependencies": { - "@types/hast": "^3.0.0", - "hastscript": "^8.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", - "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.1.0", - "hast-util-from-parse5": "^8.0.0", - "parse5": "^7.0.0", - "vfile": "^6.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html-isomorphic": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", - "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-from-dom": "^5.0.0", - "hast-util-from-html": "^2.0.0", - "unist-util-remove-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-has-property": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", - "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-body-ok-link": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-3.0.0.tgz", - "integrity": "sha512-VFHY5bo2nY8HiV6nir2ynmEB1XkxzuUffhEGeVx7orbu/B1KaGyeGgMZldvMVx5xWrDlLLG/kQ6YkJAMkBEx0w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", - "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-phrasing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/hast-util-phrasing/-/hast-util-phrasing-3.0.1.tgz", - "integrity": "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-embedded": "^3.0.0", - "hast-util-has-property": "^3.0.0", - "hast-util-is-body-ok-link": "^3.0.0", - "hast-util-is-element": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-phrasing/node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.2.tgz", - "integrity": "sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.0.tgz", - "integrity": "sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-raw": "^9.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", - "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", - "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==", - "license": "MIT" - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", - "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.2.2" - } - }, - "node_modules/hast-util-to-mdast": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-mdast/-/hast-util-to-mdast-10.1.0.tgz", - "integrity": "sha512-DsL/SvCK9V7+vfc6SLQ+vKIyBDXTk2KLSbfBYkH4zeF/uR1yBajHRhkzuaUSGOB1WJSTieJBdHwxlC+HLKvZZw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-phrasing": "^3.0.0", - "hast-util-to-html": "^9.0.0", - "hast-util-to-text": "^4.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-minify-whitespace": "^6.0.0", - "trim-trailing-lines": "^2.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.0.tgz", - "integrity": "sha512-EWiE1FSArNBPUo1cKWtzqgnuRQwEeQbQtnFJRYV1hb1BWDgrAlBU0ExptvZMM/KSA82cDpm2sFGf3Dmc5Mza3w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-text/node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "license": "MIT" - }, - "node_modules/html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", - "license": "MIT", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "license": "BSD-2-Clause" - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "license": "MIT" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "license": "MIT" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", - "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", - "license": "MIT", - "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=16.x" - } - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/infima": { - "version": "0.2.0-alpha.43", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.43.tgz", - "integrity": "sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", - "license": "MIT" - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "license": "MIT", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "license": "MIT" - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/joi": { - "version": "17.12.2", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", - "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/katex": { - "version": "0.16.9", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.9.tgz", - "integrity": "sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "license": "MIT", - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "license": "MIT", - "dependencies": { - "package-json": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "license": "MIT", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "license": "MIT" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "license": "MIT" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-definition-list": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definition-list/-/mdast-util-definition-list-2.0.0.tgz", - "integrity": "sha512-aFWuASQs77BJndNSDcNdvB1HRqWZBptcEjwv67mnPbaAZsfwMHxI8MwoQxAz4I2bHx41hft/HDRC57ZkhpayOQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.1", - "@types/unist": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-hast": "^13.0.2", - "mdast-util-to-markdown": "^2.1.0", - "micromark-extension-definition-list": "^2.0.0", - "unist-builder": "^4.0.0" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", - "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-math": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", - "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "longest-streak": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.1.0", - "unist-util-remove-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.0.tgz", - "integrity": "sha512-A8AJHlR7/wPQ3+Jre1+1rq040fX9A4Q1jG8JxmSNp/PLPHg80A6475wxTp3KzHpApFH6yWxFotHrJQA3dXP6/w==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz", - "integrity": "sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "license": "CC0-1.0" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.6.0.tgz", - "integrity": "sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ==", - "license": "Unlicense", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "license": "MIT" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-definition-list": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-definition-list/-/micromark-extension-definition-list-2.0.0.tgz", - "integrity": "sha512-92SSfTdG7YIXiYj60sNDPoo3MTJXK94LRLfKsoDHgDqiE61p4w4pzdyCc9SuoQ74/bzb5SXPVK11kjlYnIjzKA==", - "license": "MIT", - "dependencies": { - "assert": "^2.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.1", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "ts-dedent": "^2.2.0" - } - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", - "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "license": "MIT", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-math": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", - "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", - "license": "MIT", - "dependencies": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", - "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", - "license": "MIT", - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "license": "MIT", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", - "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", - "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz", - "integrity": "sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==", - "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "license": "ISC" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "license": "MIT" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "license": "MIT", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "license": "MIT" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", - "license": "MIT" - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "license": "MIT" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "license": "MIT", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "license": "MIT", - "dependencies": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/package-json/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "license": "MIT" - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-numeric-range": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", - "license": "ISC" - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "license": "MIT", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "license": "(WTFPL OR MIT)" - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", - "license": "MIT" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "license": "MIT", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "license": "MIT", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "colord": "^2.9.3", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-convert-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-comments": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-empty": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-loader": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^8.3.5", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-loader/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postcss-loader/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postcss-loader/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/postcss-merge-longhand": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-rules": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", - "license": "MIT", - "dependencies": { - "colord": "^2.9.3", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-params": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", - "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", - "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "license": "ISC", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-string": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-ordered-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", - "license": "MIT", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - }, - "engines": { - "node": "^14 || ^16 || >= 18" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "license": "MIT" - }, - "node_modules/postcss/node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/prism-react-renderer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", - "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", - "license": "MIT", - "dependencies": { - "@types/prismjs": "^1.26.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.0.0" - } - }, - "node_modules/prism-react-renderer/node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/property-information": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", - "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "license": "ISC" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", - "license": "MIT", - "dependencies": { - "escape-goat": "^4.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "license": "MIT", - "dependencies": { - "inherits": "~2.0.3" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", - "license": "MIT" - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "license": "MIT" - }, - "node_modules/react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-icons": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", - "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", - "license": "MIT", - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/react-json-view-lite": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.2.1.tgz", - "integrity": "sha512-Itc0g86fytOmKZoIoJyGgvNqohWSbh3NXIKNgH6W6FT9PC1ck4xas1tT3Rr/b3UlFXyA9Jjaw9QSXdZy2JwGMQ==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-loadable": { - "name": "@docusaurus/react-loadable", - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", - "license": "MIT", - "dependencies": { - "@types/react": "*" - }, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.10.3" - }, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "react-loadable": "*", - "webpack": ">=4.41.1 || 5.x" - } - }, - "node_modules/react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router-config": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2" - }, - "peerDependencies": { - "react": ">=15", - "react-router": ">=5" - } - }, - "node_modules/react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reading-time": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==", - "license": "MIT" - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "license": "MIT" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "license": "MIT" - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "license": "MIT", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "license": "MIT", - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "license": "MIT", - "dependencies": { - "rc": "1.2.8" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/rehype-katex": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", - "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/katex": "^0.16.0", - "hast-util-from-html-isomorphic": "^2.0.0", - "hast-util-to-text": "^4.0.0", - "katex": "^0.16.0", - "unist-util-visit-parents": "^6.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-minify-whitespace": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-minify-whitespace/-/rehype-minify-whitespace-6.0.0.tgz", - "integrity": "sha512-i9It4YHR0Sf3GsnlR5jFUKXRr9oayvEk9GKQUkwZv6hs70OH9q3OCZrq9PpLvIGKt3W+JxBOxCidNVpH/6rWdA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-embedded": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-minify-whitespace/node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remark-definition-list": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-definition-list/-/remark-definition-list-2.0.0.tgz", - "integrity": "sha512-OOJ0zUrfUGITUNxOBnsipyFUjqq1m4AgYOqQk10jDXyz+RoODJL3qYvRn8qzYQDzRnz1wlCP3dbDEOpl05LlQw==", - "license": "MIT", - "dependencies": { - "hast-util-definition-list": "^2.0.0", - "mdast-util-definition-list": "^2.0.0", - "micromark-extension-definition-list": "^2.0.0" - } - }, - "node_modules/remark-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", - "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-emoji": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.2", - "emoticon": "^4.0.1", - "mdast-util-find-and-replace": "^3.0.1", - "node-emoji": "^2.1.0", - "unified": "^11.0.4" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-math": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", - "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-math": "^3.0.0", - "micromark-extension-math": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", - "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", - "license": "MIT", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", - "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "license": "MIT", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/renderkid/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", - "engines": { - "node": "*" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "license": "MIT" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", - "license": "MIT" - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "license": "MIT", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rtl-detect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", - "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==", - "license": "BSD-3-Clause" - }, - "node_modules/rtlcss": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", - "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", - "license": "MIT", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0", - "postcss": "^8.4.21", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "rtlcss": "bin/rtlcss.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", - "license": "ISC" - }, - "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/search-insights": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", - "license": "MIT", - "peer": true - }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "license": "MIT" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "license": "MIT", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver-diff/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-handler": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", - "license": "MIT", - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - } - }, - "node_modules/serve-handler/node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-handler/node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "license": "MIT", - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-handler/node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "license": "MIT", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "license": "ISC" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "license": "ISC" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "license": "MIT", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/server-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", - "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", - "license": "MIT" - }, - "node_modules/set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.2", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "license": "BSD-3-Clause", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/side-channel": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", - "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "license": "MIT" - }, - "node_modules/sitemap": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", - "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", - "license": "MIT", - "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "bin": { - "sitemap": "dist/cli.js" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=5.6.0" - } - }, - "node_modules/sitemap/node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", - "license": "MIT" - }, - "node_modules/skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "license": "MIT", - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sort-css-media-queries": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", - "license": "MIT", - "engines": { - "node": ">= 6.3.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "license": "MIT" - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "license": "MIT" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "license": "BSD-2-Clause", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/stylehacks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", - "license": "MIT" - }, - "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "license": "MIT", - "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" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/svgo/node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/svgo/node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/svgo/node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "license": "CC0-1.0" - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.27.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.2.tgz", - "integrity": "sha512-sHXmLSkImesJ4p5apTeT63DsV4Obe1s37qT8qvwHRmVxKTBH7Rv9Wr26VcAMmLbmk9UliiwK8z+657NyJHHy/w==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "license": "MIT" - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "license": "MIT" - }, - "node_modules/tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", - "license": "MIT" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", - "license": "MIT" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trim-trailing-lines": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-2.1.0.tgz", - "integrity": "sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", - "license": "MIT", - "engines": { - "node": ">=6.10" - } - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "license": "MIT" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "license": "MIT", - "dependencies": { - "crypto-random-string": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unist-builder": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-4.0.0.tgz", - "integrity": "sha512-wmRFnH+BLpZnTKpc5L7O67Kac89s9HMrtELpnNaE6TAobq5DTZZs5YaTQfAZBA9bFPECx2uVAPO31c+GVug8mg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/update-notifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", - "license": "BSD-2-Clause", - "dependencies": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", - "configstore": "^6.0.0", - "has-yarn": "^3.0.0", - "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", - "is-installed-globally": "^0.4.0", - "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", - "latest-version": "^7.0.0", - "pupa": "^3.1.0", - "semver": "^7.3.7", - "semver-diff": "^4.0.0", - "xdg-basedir": "^5.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/update-notifier/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/update-notifier/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "license": "MIT" - }, - "node_modules/utility-types": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", - "license": "MIT" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/webpack": { - "version": "5.90.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", - "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", - "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "is-plain-object": "^5.0.0", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpackbar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.3", - "pretty-time": "^1.1.0", - "std-env": "^3.0.1" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "webpack": "3 || 4 || 5" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.6", - "call-bind": "^1.0.5", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "license": "MIT", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "license": "MIT" - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xml-js": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "license": "MIT", - "dependencies": { - "sax": "^1.2.4" - }, - "bin": { - "xml-js": "bin/cli.js" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "license": "ISC" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/package.json b/package.json index 307355a71e..9f51442da0 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,17 @@ "write-heading-ids": "docusaurus write-heading-ids" }, "dependencies": { - "@docusaurus/core": "^3.4.0", - "@docusaurus/plugin-client-redirects": "^3.4.0", - "@docusaurus/preset-classic": "^3.4.0", + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "^3.7.0", + "@docusaurus/plugin-client-redirects": "^3.7.0", + "@docusaurus/plugin-content-docs": "^3.7.0", + "@docusaurus/preset-classic": "^3.7.0", + "@docusaurus/theme-classic": "^3.7.0", + "@docusaurus/theme-common": "^3.7.0", + "@docusaurus/theme-search-algolia": "^3.7.0", "@gracefullight/docusaurus-plugin-vercel-analytics": "^1.0.0", "@mdx-js/react": "^3.0.0", + "@polkadot/api": "^16.4.8", "@vercel/analytics": "^1.1.2", "clsx": "^1.2.1", "hast-util-is-element": "1.1.0", @@ -33,9 +39,9 @@ "zwitch": "^2.0.4" }, "devDependencies": { - "@docusaurus/module-type-aliases": "^3.3.2", - "@docusaurus/tsconfig": "^3.3.2", - "@docusaurus/types": "^3.3.2", + "@docusaurus/module-type-aliases": "^3.7.0", + "@docusaurus/tsconfig": "^3.7.0", + "@docusaurus/types": "^3.7.0", "typescript": "~5.2.2" }, "browserslist": { @@ -69,5 +75,6 @@ "RetentionPolicy": "Retain" } } - } + }, + "packageManager": "yarn@4.9.1" } diff --git a/sidebars.js b/sidebars.js index 50671bc630..c0f04d5259 100644 --- a/sidebars.js +++ b/sidebars.js @@ -16,70 +16,137 @@ const sidebars = { bittensorSidebar: [ // { // type: 'link', - // href: 'https://docs.bittensor.com', + // href: 'https://docs.learnbittensor.org', // label: "Search", // className: 'sidebarSearch', // based on Class name it will add search component // }, "index", { - type: 'doc', - id: 'bittensor-rel-notes', - label: 'Releases', + type: "category", + label: "Releases and Announcements", + collapsible: true, + collapsed: true, + items: [ + { + type: "doc", + id: "resources/bittensor-rel-notes", + label: "Releases", + }, + { + type: "doc", + id: "learn/announcements", + label: "Announcements", + }, + ], }, - "btcli/btcli-playground", { type: "category", label: "Understand Bittensor", - link: {type: "doc", id: "learn/introduction"}, + link: { type: "doc", id: "learn/introduction" }, collapsible: true, collapsed: true, items: [ "learn/introduction", - "questions-and-answers", - "subnets/understanding-subnets", - "learn/bittensor-building-blocks", + "resources/questions-and-answers", + "subnets/understanding-subnets", "learn/anatomy-of-incentive-mechanism", - "emissions", - "yuma-consensus", + + "subnets/understanding-multiple-mech-subnets", + "learn/neurons", + + "learn/emissions", + "learn/ema", + "learn/yuma-consensus", + "learn/yc3-blog", + "concepts/weight-copying-in-bittensor", + "learn/yuma3-migration-guide", + "learn/fees", + "learn/chain-rate-limits", + { + type: "category", + label: "Navigating Subtensor Codebase", + link: { type: "doc", id: "navigating-subtensor/index" }, + collapsible: true, + collapsed: true, + items: [ + "navigating-subtensor/emissions-coinbase", + "navigating-subtensor/epoch", + "navigating-subtensor/swap-stake", + ], + }, + "resources/community-links", ], }, { type: "category", - label: "Staking/Delegation", + label: "Wallets and Keys", collapsible: true, collapsed: true, - link: {type: "doc", id: "staking-and-delegation/delegation",}, items: [ - "staking-and-delegation/delegation", - "staking-and-delegation/stakers-btcli-guide", - "dynamic-tao/staking-unstaking-dtao", - "staking-and-delegation/managing-stake-btcli", - "staking-and-delegation/managing-stake-sdk", - "staking-and-delegation/staking-polkadot-js", - "staking-and-delegation/using-ledger-hw-wallet"], + "keys/wallets", + "keys/working-with-keys", + "keys/handle-seed-phrase", + "keys/coldkey-hotkey-security", + "keys/address-poisoning-scams", + { + type: "category", + label: "Proxies", + collapsible: true, + collapsed: true, + link: { type: "doc", id: "keys/proxies/index" }, + items: ["keys/proxies/create-proxy", "keys/proxies/pure-proxies"], + }, + "keys/multisig", + "keys/schedule-coldkey-swap", + ], }, + { type: "category", - label: "Mining", + label: "Staking/Delegation", collapsible: true, collapsed: true, - link: {type: "doc", id: "miners/index",}, + link: { type: "doc", id: "staking-and-delegation/delegation" }, items: [ - "miners/index", - "miners/miners-btcli-guide" + "staking-and-delegation/delegation", + "staking-and-delegation/stakers-btcli-guide", + "staking-and-delegation/managing-stake-btcli", + "staking-and-delegation/managing-stake-sdk", + "learn/price-protection", + "learn/slippage", + "staking-and-delegation/staking-polkadot-js", + "staking-and-delegation/using-ledger-hw-wallet", ], }, + { + type: "category", + label: "Mining", + collapsible: true, + collapsed: true, + link: { type: "doc", id: "miners/index" }, + items: ["miners/index", "miners/miners-btcli-guide", "miners/autostaking"], + }, { type: "category", label: "Validating", collapsible: true, collapsed: true, - link: {type: "doc", id: "validators/index",}, + link: { type: "doc", id: "validators/index" }, items: [ - "validators/index", - "subnets/child-hotkeys", - "validators/validators-btcli-guide" + "validators/index", + "validators/child-hotkeys", + "validators/validators-btcli-guide", + ], + }, + { + type: "category", + label: "Liquidity Positions (Uniswap)", + collapsible: true, + collapsed: true, + items: [ + "liquidity-positions/liquidity-positions", + "liquidity-positions/managing-liquidity-positions", ], }, { @@ -88,147 +155,166 @@ const sidebars = { collapsible: true, collapsed: true, items: [ + "subnets/metagraph", "subnets/create-a-subnet", + { + type: "category", + label: "Crowdloans", + collapsible: true, + collapsed: true, + link: { type: "doc", id: "subnets/crowdloans/index" }, + items: ["subnets/crowdloans/crowdloans-tutorial"], + }, "subnets/subnet-creators-btcli-guide", "subnets/subnet-hyperparameters", "subnets/working-with-subnets", + "subnets/managing-mechanisms-with-sdk", + "subnets/managing-mechanisms-btcli", + "subnets/uid-trimming", + "subnets/subnet-deregistration", "subnets/walkthrough-prompting", "tutorials/basic-subnet-tutorials", "tutorials/ocr-subnet-tutorial", ], }, - { - type: "category", - label: "BTCLI: The Bittensor CLI", - collapsible: true, - collapsed: true, - link: {type: "doc", id: "btcli/overview",}, - items: [ - "getting-started/install-btcli", - "btcli/btcli-playground", - "btcli-permissions", - "btcli", - "staking-and-delegation/managing-stake-btcli", - ] - }, - { - type: "category", - label: "Bittensor Python SDK", - collapsible: true, - collapsed: true, - items: [ - "getting-started/installation", - "sdk/env-vars", - "bt-api-ref", - "sdk/subtensor-api", - "getting-started/install-wallet-sdk", - "migration_guide", - "subnets/asyncio", - "sdk/managing-subtensor-connections", - - ] - }, - - { - type: "category", - label: "Wallets and Keys", - collapsible: true, - collapsed: true, - items: [ - "getting-started/wallets", - "keys/handle-seed-phrase", - "getting-started/coldkey-hotkey-security", - "working-with-keys", - "keys/multisig", - "subnets/schedule-coldkey-swap", - ] - }, + { + type: "category", + label: "BTCLI: The Bittensor CLI", + collapsible: true, + collapsed: true, + link: { type: "doc", id: "btcli/overview" }, + items: [ + "getting-started/install-btcli", + "btcli/btcli-playground", + "btcli/btcli-permissions", + "btcli/btcli", + "staking-and-delegation/managing-stake-btcli", + ], + }, + { + type: "category", + label: "Bittensor Python SDK", + collapsible: true, + collapsed: true, + items: [ + "getting-started/installation", + "sdk/env-vars", + "sdk/bt-api-ref", + "sdk/subtensor-api", + "getting-started/install-wallet-sdk", + "sdk/migration-guide", + "subnets/asyncio", + "sdk/managing-subtensor-connections", + ], + }, + { type: "category", label: "Tools and Special Features", - link: {type: "doc", id: "tools",}, + link: { type: "doc", id: "concepts/tools" }, collapsible: true, collapsed: true, items: [ - "bittensor-networks", - "subnets/commit-reveal", - "subnets/consensus-based-weights", - "subnets/bt-logging-levels", - "utilities", + "concepts/bittensor-networks", + "concepts/commit-reveal", + "concepts/consensus-based-weights", + "concepts/bt-logging-levels", + "resources/utilities", ], }, { type: "category", label: "Local Development", - link: {type: "doc", id: "local-build/deploy",}, + link: { type: "doc", id: "local-build/deploy" }, collapsible: true, collapsed: true, items: [ "local-build/deploy", "local-build/provision-wallets", "local-build/create-subnet", - // "local-build/mine-validate" + "local-build/mine-validate", ], }, - -{ + { type: "category", label: "Subtensor Nodes", - link: {type: "doc", id: "subtensor-nodes/index",}, + link: { type: "doc", id: "subtensor-nodes/index" }, collapsible: true, collapsed: true, items: [ "subtensor-nodes/subtensor-node-requirements", "subtensor-nodes/using-source", "subtensor-nodes/using-docker", - "subtensor-nodes/subtensor-rate-limits", "subtensor-nodes/subtensor-storage-query-examples", ], }, - + { type: "category", - label: "EVM smart contracts on Bittensor", - link: {type: "doc", id: "evm-tutorials/index",}, - collapsible: true, - collapsed: true, + label: "Bittensor EVM", + link: { type: "doc", id: "evm-tutorials/index" }, items: [ - "evm-tutorials/evm-on-subtensor", - "evm-tutorials/install", + "evm-tutorials/index", + "evm-tutorials/subtensor-networks", + "evm-tutorials/bridge-vtao", "evm-tutorials/evm-testnet-with-metamask-wallet", "evm-tutorials/evm-localnet-with-metamask-wallet", "evm-tutorials/evm-mainnet-with-metamask-wallet", + "evm-tutorials/hardhat-config-for-subtensor-evm", + "evm-tutorials/remix-config-for-subtensor-evm", + "evm-tutorials/bridge-vtao", + "evm-tutorials/troubleshooting", + ], + }, + { + type: "category", + link: { type: "doc", id: "evm-tutorials/examples" }, + label: "Bittensor EVM: Examples and Precompiles", + items: [ + "evm-tutorials/examples", + "evm-tutorials/convert-h160-to-ss58", "evm-tutorials/transfer-from-metamask-to-ss58", "evm-tutorials/transfer-between-two-h160-accounts", - "evm-tutorials/hardhat-config-for-subtensor-evm", - "evm-tutorials/staking-precompile", + "evm-tutorials/withdraw-from-alice", "evm-tutorials/ed25519-verify-precompile", + "evm-tutorials/staking-precompile", + "evm-tutorials/subnet-precompile", + "evm-tutorials/metagraph-precompile", + "evm-tutorials/neuron-precompile", ], }, + // { + // type: "category", + // label: "Bittensor EVM Smart Contracts", + // link: {type: "doc", id: "evm-tutorials/index",}, + // collapsible: true, + // collapsed: true, + // items: [ + // "evm-tutorials/install", + // , + + // ], + // }, { type: "category", label: "Governance", collapsible: true, collapsed: true, items: [ - "governance", - "senate", - "governance/senators-btcli-guide" + "governance/governance", + "governance/senate", + "governance/senators-btcli-guide", ], - }, { + }, + { type: "category", label: "Dynamic TAO", - link: {type: "doc", id: "dynamic-tao/index",}, + link: { type: "doc", id: "dynamic-tao/index" }, collapsible: true, collapsed: true, - items: [ - "dynamic-tao/dtao-guide", - "dynamic-tao/dtao-faq", - "dynamic-tao/sdk-cheat-sheet", - - ], + items: ["dynamic-tao/dtao-faq", "dynamic-tao/sdk-cheat-sheet"], }, { @@ -236,19 +322,18 @@ const sidebars = { label: "Errors and Troubleshooting", collapsible: true, collapsed: true, - link: {type: "doc", id: "errors/index",}, + link: { type: "doc", id: "errors/index" }, items: [ "errors/index", "errors/custom", "errors/subtensor", - "errors-and-troubleshooting", + "errors/troubleshooting", ], }, - "media-assets", - "glossary", - + "resources/glossary", + "resources/community-links", + "resources/media-assets", ], - }; module.exports = sidebars; diff --git a/src/css/style.css b/src/css/style.css index f020351b1d..abed8f7db4 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -6,1508 +6,1558 @@ /* You can override the default Infima variables here. */ :root { - --ifm-color-primary: rgba(14, 16, 19, 1); - --ifm-color-primary-dark: #29784c; - --ifm-color-primary-darker: #277148; - --ifm-color-primary-darkest: #205d3b; - --ifm-color-primary-light: black; - --ifm-color-primary-lighter: #359962; - --ifm-color-primary-lightest: #3cad6e; - --ifm-code-font-size: 95%; - --ifm-h1-font-size: 1.8rem; - --ifm-h2-font-size: 1.5rem; - --ifm-h3-font-size: 1.2rem; - --ifm-h4-font-size: 1rem; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); - --text-primary: #5f6368; - --text-secondary: #5f6368; - --grey-100: #f8f9fa; /* --contrast-100 */ - --grey-900: #0e1013; /* --border-dashed-primary-hk */ - --ifm-menu-color-background-hover: var(--grey-100) + --ifm-color-primary: rgba(14, 16, 19, 1); + --ifm-color-primary-dark: #29784c; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205d3b; + --ifm-color-primary-light: black; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-lightest: #3cad6e; + --ifm-code-font-size: 95%; + --ifm-h1-font-size: 1.8rem; + --ifm-h2-font-size: 1.5rem; + --ifm-h3-font-size: 1.2rem; + --ifm-h4-font-size: 1rem; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); + --text-primary: #5f6368; + --text-secondary: #5f6368; + --grey-100: #f8f9fa; /* --contrast-100 */ + --grey-900: #0e1013; /* --border-dashed-primary-hk */ + --ifm-menu-color-background-hover: var(--grey-100); } /* For readability concerns, you should choose a lighter palette in dark mode. */ [data-theme="dark"] { - --ifm-color-primary: white; - --ifm-color-primary-dark: white; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: #29d5b0; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); - --ifm-background-surface-color: #000000 !important; - --ifm-background-color: #000000 !important; - --ifm-navbar-active-color: white; - --ifm-navbar-item-color: #a5abaf; - --ifm-footer-div-color: black; - --ifm-table-of-contents-border: rgba(40, 42, 45, 1); - --ifm-table-of-contents-border-active: rgba(248, 249, 250, 1); - --ifm-table-of-contents-text: #a5abaf; - --ifm-table-of-contents-text-active: white; - --ifm-breadcrumbs__item--active: rgba(248, 249, 250, 1); - --ifm-menu__link--active: #5f6368; - --ifm-dropdown-background-color: #242526 !important; - --ifm-footer-bg: #0E1013; - --ifm-footer-company-name-color: white; - --ifm-algolia-bg: #242526; - --ifm-algolia-border: #7f8497; - --ifm-navbar-border: #282A2D; - --ifm-alert-secondary: rgba(235, 237, 240, 0.15); - --ifm-alert-success: rgba(0, 164, 0, 0.15); - --ifm-alert-info: rgba(84, 199, 236, 0.15); - --ifm-alert-warning: rgba(255, 186, 0, 0.15); - --ifm-alert-danger: rgba(250, 56, 62, 0.15); - --ifm-blockquote-border: #606770; - --ifm-tab-container-active-bg: white; - --ifm-tab-container-active-color: black; - --ifm-ul: #f5f6f7; - --ifm-hr: rgba(95, 99, 104, 1); - --ifm-search-icon-color: #a5abaf; - --ifm-doc-search-border-color: #000000; - --ifm-table-header-bg: #2B2B2D; - --ifm-table-header-color: white; - --ifm-table-body-color: #D7E3E3; - --ifm-table-tr-border: #3c3e42; - --ifm-doc-search-title-color: white; - --ifm-dock-search-active-a-bg: #000000; - --ifm-dock-search-active-a-color: white; - --ifm-dock-search-svg-color: white; - --ifm-doc-search-title-bg: #242526; + --ifm-color-primary: white; + --ifm-color-primary-dark: white; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); + --ifm-background-surface-color: #000000 !important; + --ifm-background-color: #000000 !important; + --ifm-navbar-active-color: white; + --ifm-navbar-item-color: #a5abaf; + --ifm-footer-div-color: black; + --ifm-table-of-contents-border: rgba(40, 42, 45, 1); + --ifm-table-of-contents-border-active: rgba(248, 249, 250, 1); + --ifm-table-of-contents-text: #a5abaf; + --ifm-table-of-contents-text-active: white; + --ifm-breadcrumbs__item--active: rgba(248, 249, 250, 1); + --ifm-menu__link--active: #5f6368; + --ifm-dropdown-background-color: #242526 !important; + --ifm-footer-bg: #0e1013; + --ifm-footer-company-name-color: white; + --ifm-algolia-bg: #242526; + --ifm-algolia-border: #7f8497; + --ifm-navbar-border: #282a2d; + --ifm-alert-secondary: rgba(235, 237, 240, 0.15); + --ifm-alert-success: rgba(0, 164, 0, 0.15); + --ifm-alert-info: rgba(84, 199, 236, 0.15); + --ifm-alert-warning: rgba(255, 186, 0, 0.15); + --ifm-alert-danger: rgba(250, 56, 62, 0.15); + --ifm-blockquote-border: #606770; + --ifm-tab-container-active-bg: white; + --ifm-tab-container-active-color: black; + --ifm-ul: #f5f6f7; + --ifm-hr: rgba(95, 99, 104, 1); + --ifm-search-icon-color: #a5abaf; + --ifm-doc-search-border-color: #000000; + --ifm-table-header-bg: #2b2b2d; + --ifm-table-header-color: white; + --ifm-table-body-color: #d7e3e3; + --ifm-table-tr-border: #3c3e42; + --ifm-doc-search-title-color: white; + --ifm-dock-search-active-a-bg: #000000; + --ifm-dock-search-active-a-color: white; + --ifm-dock-search-svg-color: white; + --ifm-doc-search-title-bg: #242526; } [data-theme="light"] { - --ifm-color-primary: black; - --ifm-color-primary-dark: white; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: black; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); - --ifm-navbar-active-color: black; - --ifm-navbar-item-color: rgb(111, 112, 114); - --ifm-footer-div-color: white; - --ifm-table-of-contents-border: rgba(219, 221, 225, 1); - --ifm-table-of-contents-border-active: black; - --ifm-table-of-contents-text: #5F6368; - --ifm-table-of-contents-text-active: #0E1013; - --ifm-breadcrumbs__item--active: rgba(14, 16, 19, 1); - --ifm-menu__link--active: rgb(111, 112, 114); - --ifm-footer-bg: #0E1013; - --ifm-footer-company-name-color: white; - --ifm-algolia-bg: white; - --ifm-algolia-border: #0E1013; - --ifm-navbar-border: #DBDDE1; - --ifm-alert-secondary: #F8F9FA; - --ifm-alert-success: #E6F5E6; - --ifm-alert-info: #EEF9FC; - --ifm-alert-warning: #FFF8E6; - --ifm-alert-danger: #FFEBEC; - --ifm-blockquote-border: #DBDDE1; - --ifm-tab-container-active-bg: black; - --ifm-tab-container-active-color: white; - --ifm-ul: rgba(95, 99, 104, 1); - --ifm-hr: rgba(14, 16, 19, 1); - --ifm-search-icon-color: #1c1e21; - --ifm-doc-search-border-color: rgba(219, 221, 225, 1); - --ifm-table-header-bg: #F8F9FA; - --ifm-table-header-color: #5F6368; - --ifm-table-body-color: rgba(95, 99, 104, 1); - --ifm-table-tr-border: rgba(14, 16, 19, 1); - --ifm-doc-search-title-color: rgba(14, 16, 19, 1); - --ifm-dock-search-active-a-bg: white; - --ifm-dock-search-active-a-color: #000000; - --ifm-dock-search-svg-color: rgba(14, 16, 19, 1); - --ifm-doc-search-title-bg: white; + --ifm-color-primary: black; + --ifm-color-primary-dark: white; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: black; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); + --ifm-navbar-active-color: black; + --ifm-navbar-item-color: rgb(111, 112, 114); + --ifm-footer-div-color: white; + --ifm-table-of-contents-border: rgba(219, 221, 225, 1); + --ifm-table-of-contents-border-active: black; + --ifm-table-of-contents-text: #5f6368; + --ifm-table-of-contents-text-active: #0e1013; + --ifm-breadcrumbs__item--active: rgba(14, 16, 19, 1); + --ifm-menu__link--active: rgb(111, 112, 114); + --ifm-footer-bg: #0e1013; + --ifm-footer-company-name-color: white; + --ifm-algolia-bg: white; + --ifm-algolia-border: #0e1013; + --ifm-navbar-border: #dbdde1; + --ifm-alert-secondary: #f8f9fa; + --ifm-alert-success: #e6f5e6; + --ifm-alert-info: #eef9fc; + --ifm-alert-warning: #fff8e6; + --ifm-alert-danger: #ffebec; + --ifm-blockquote-border: #dbdde1; + --ifm-tab-container-active-bg: black; + --ifm-tab-container-active-color: white; + --ifm-ul: rgba(95, 99, 104, 1); + --ifm-hr: rgba(14, 16, 19, 1); + --ifm-search-icon-color: #1c1e21; + --ifm-doc-search-border-color: rgba(219, 221, 225, 1); + --ifm-table-header-bg: #f8f9fa; + --ifm-table-header-color: #5f6368; + --ifm-table-body-color: rgba(95, 99, 104, 1); + --ifm-table-tr-border: rgba(14, 16, 19, 1); + --ifm-doc-search-title-color: rgba(14, 16, 19, 1); + --ifm-dock-search-active-a-bg: white; + --ifm-dock-search-active-a-color: #000000; + --ifm-dock-search-svg-color: rgba(14, 16, 19, 1); + --ifm-doc-search-title-bg: white; } - @font-face { - font-family: "Haffer"; - src: url(../../static/fonts/Haffer-Light.ttf); - font-weight: 200; - font-style: normal; + font-family: "Haffer"; + src: url(../../static/fonts/Haffer-Light.ttf); + font-weight: 200; + font-style: normal; } @font-face { - font-family: "Haffer"; - src: url(../../static/fonts/Haffer-Medium.ttf); - font-weight: 400; - font-style: normal; + font-family: "Haffer"; + src: url(../../static/fonts/Haffer-Medium.ttf); + font-weight: 400; + font-style: normal; } @font-face { - font-family: "Haffer"; - src: url(../../static/fonts/Haffer-Regular.ttf); - font-weight: normal; - font-style: normal; + font-family: "Haffer"; + src: url(../../static/fonts/Haffer-Regular.ttf); + font-weight: normal; + font-style: normal; } @font-face { - font-family: "Haffer"; - src: url(../../static/fonts/Haffer-SemiBold.ttf); - font-weight: bold; - font-style: normal; + font-family: "Haffer"; + src: url(../../static/fonts/Haffer-SemiBold.ttf); + font-weight: bold; + font-style: normal; } @font-face { - font-family: "HafferSQ"; - src: url(../../static/fonts/HafferSQ-Light.ttf); - font-weight: 200; - font-style: normal; + font-family: "HafferSQ"; + src: url(../../static/fonts/HafferSQ-Light.ttf); + font-weight: 200; + font-style: normal; } @font-face { - font-family: "HafferSQ"; - src: url(../../static/fonts/HafferSQ-Medium.ttf); - font-weight: 400; - font-style: normal; + font-family: "HafferSQ"; + src: url(../../static/fonts/HafferSQ-Medium.ttf); + font-weight: 400; + font-style: normal; } @font-face { - font-family: "HafferSQ"; - src: url(../../static/fonts/HafferSQ-Regular.ttf); - font-weight: normal; - font-style: normal; + font-family: "HafferSQ"; + src: url(../../static/fonts/HafferSQ-Regular.ttf); + font-weight: normal; + font-style: normal; } @font-face { - font-family: "HafferSQ"; - src: url(../../static/fonts/HafferSQ-SemiBold.ttf); - font-weight: bold; - font-style: normal; + font-family: "HafferSQ"; + src: url(../../static/fonts/HafferSQ-SemiBold.ttf); + font-weight: bold; + font-style: normal; } @font-face { - font-family: "TTCommonsPro"; - src: url(../../static/fonts/TTCommonsProMonoMedium.ttf); - font-weight: 200; - font-style: normal; + font-family: "TTCommonsPro"; + src: url(../../static/fonts/TTCommonsProMonoMedium.ttf); + font-weight: 200; + font-style: normal; } @font-face { - font-family: "TTCommonsPro"; - src: url(../../static/fonts/TTCommonsProMonoRegular.ttf); - font-weight: 100; - font-style: normal; + font-family: "TTCommonsPro"; + src: url(../../static/fonts/TTCommonsProMonoRegular.ttf); + font-weight: 100; + font-style: normal; } @font-face { - font-family: "FiraCode"; - src: url(../../static/fonts/FiraCode_VariableFont_wght.ttf); + font-family: "FiraCode"; + src: url(../../static/fonts/FiraCode_VariableFont_wght.ttf); } @font-face { - font-family: "DM Mono"; - src: url(../../static/fonts/DMMono-Regular.ttf); - font-weight: normal; - font-style: normal; + font-family: "DM Mono"; + src: url(../../static/fonts/DMMono-Regular.ttf); + font-weight: normal; + font-style: normal; } @font-face { - font-family: "DM Mono"; - src: url(../../static/fonts/DMMono-Medium.ttf); - font-weight: 500; - font-style: normal; + font-family: "DM Mono"; + src: url(../../static/fonts/DMMono-Medium.ttf); + font-weight: 500; + font-style: normal; } body { - font-family: "Haffer"; - font-size: 16px; - font-weight: 200; - letter-spacing: 0%; - line-height: 160%; + font-family: "Haffer"; + font-size: 16px; + font-weight: 200; + letter-spacing: 0%; + line-height: 160%; } .h1 { - font-family: "Haffer"; - font-size: 32px; - font-weight: 400; - letter-spacing: calc(-0.01 * 20px); - line-height: 120%; + font-family: "Haffer"; + font-size: 32px; + font-weight: 400; + letter-spacing: calc(-0.01 * 20px); + line-height: 120%; } .h2 { - font-family: "Haffer"; - font-size: 24px; - font-weight: 400; - letter-spacing: calc(-0.01 * 20px); - line-height: 120%; + font-family: "Haffer"; + font-size: 24px; + font-weight: 400; + letter-spacing: calc(-0.01 * 20px); + line-height: 120%; } .h3 { - font-family: "Haffer"; - font-size: 20px; - font-weight: 400; - letter-spacing: 0%; - line-height: 120%; + font-family: "Haffer"; + font-size: 20px; + font-weight: 400; + letter-spacing: 0%; + line-height: 120%; } .h4 { - font-family: "Haffer"; - font-size: 16px; - font-weight: bold; - letter-spacing: 0%; - line-height: 140%; + font-family: "Haffer"; + font-size: 16px; + font-weight: bold; + letter-spacing: 0%; + line-height: 140%; } a { - /* color: rgb(0, 49, 0); */ - color: none; - font-weight: 400; + /* color: rgb(0, 49, 0); */ + color: none; + font-weight: 400; } - h1 { - font-weight: 400 !important; - font-size: 32px !important; - padding-bottom: 22px !important; - margin-top: -16px !important; + font-weight: 400 !important; + font-size: 32px !important; + padding-bottom: 22px !important; + margin-top: -16px !important; } h1.anchor { - font-weight: 400 !important; - font-size: 32px !important; + font-weight: 400 !important; + font-size: 32px !important; } h2 { - font-weight: 400 !important; - font-size: 24px !important; + font-weight: 400 !important; + font-size: 24px !important; } h2.anchor { - font-weight: 400 !important; - font-size: 24px !important; + font-weight: 400 !important; + font-size: 24px !important; } h3 { - font-weight: 400 !important; - font-size: 20px !important; + font-weight: 400 !important; + font-size: 20px !important; } h3.anchor { - font-weight: 400 !important; - font-size: 20px !important; + font-weight: 400 !important; + font-size: 20px !important; } h4 { - font-size: 16px !important; - font-weight: bold !important; + font-size: 16px !important; + font-weight: bold !important; } h4.anchor { - font-size: 16px !important; - font-weight: bold !important; + font-size: 16px !important; + font-weight: bold !important; } p { - font-size: 16px !important; - font-weight: 400 !important; + font-size: 16px !important; + font-weight: 400 !important; } .menu__list { - list-style: none; - margin: 0 !important; - padding-left: 0 !important; - font-family: "FiraCode"; - font-size: 12px; - font-weight: 400; - letter-spacing: calc(0.05 * 12px); - line-height: 150%; - text-transform: uppercase; + list-style: none; + margin: 0 !important; + padding-left: 0 !important; + font-family: "FiraCode"; + font-size: 12px; + font-weight: 400; + letter-spacing: calc(0.05 * 12px); + line-height: 150%; + text-transform: uppercase; } .theme-doc-sidebar-item-category > ul > li > a { - padding-left: 48px; + padding-left: 48px; } .theme-doc-sidebar-container > div > div { - padding-top: 96px !important; - margin-top: -96px !important; + padding-top: 96px !important; + margin-top: -96px !important; +} + +li.theme-doc-sidebar-item-category.theme-doc-sidebar-item-category-level-2 + > div + a.menu__link { + padding-left: 3rem !important; +} + +li.theme-doc-sidebar-item-category.theme-doc-sidebar-item-category-level-2 { + position: relative; +} + +li.theme-doc-sidebar-item-category.theme-doc-sidebar-item-category-level-2::after { + content: ""; + background-position: 0 0; + background-image: linear-gradient( + to right, + var(--grey-900), + 1.5px, + transparent 1.5px + ); + background-repeat: repeat-x; + background-size: 6px; + display: block; + width: 100%; + height: 1.5px; + position: absolute; + bottom: 0px; + left: 0; +} + +li.theme-doc-sidebar-item-link-level-3 a { + padding-left: 4.5rem !important; } .table-of-contents, .table-of-contents ul { - font-family: "FiraCode"; + font-family: "FiraCode"; } [class*="tableOfContents"] { - padding-top: 20px; + padding-top: 20px; } .pagination-nav__link--prev .pagination-nav__label::before { - content: ""; + content: ""; } .pagination-nav__link--next .pagination-nav__label::after { - content: ""; + content: ""; } .pagination-nav__link { - border: none; + border: none; } .navbar__link { - font-size: 12px; - font-weight: 500; - font-family: 'DM Mono', monospace; - color: var(--text-secondary); - letter-spacing: 0.6px; + font-size: 12px; + font-weight: 500; + font-family: "DM Mono", monospace; + color: var(--text-secondary); + letter-spacing: 0.6px; } [data-theme="dark"] .navbar__link:hover { - color:#e3e3e3 !important; + color: #e3e3e3 !important; } .navbar__link:hover { - color: #000 !important; + color: #000 !important; } .theme-last-updated { - font-style: normal; - font-weight: 400; - font-size: 9px; - text-transform: uppercase; - font-family: "FiraCode"; + font-style: normal; + font-weight: 400; + font-size: 9px; + text-transform: uppercase; + font-family: "FiraCode"; } .parameter-label { - display: inline-block; - position: relative; - top: 3px; - color: #fff; - text-transform: uppercase; - font-size: 11px; - font-weight: 700; - padding: 1px 5px; + display: inline-block; + position: relative; + top: 3px; + color: #fff; + text-transform: uppercase; + font-size: 11px; + font-weight: 700; + padding: 1px 5px; } .success { - background: #859900; + background: #859900; } .important { - background: #dc322f; + background: #dc322f; } - ul { - font-family: "Haffer"; - font-weight: 200; - text-transform: none; + font-family: "Haffer"; + font-weight: 200; + text-transform: none; } .navbar { - margin-bottom: 10px; + margin-bottom: 10px; } .sidebar-title { - font-size: 1rem; - font-family: "Haffer"; - font-weight: 500; - letter-spacing: 0.05em; - margin: 0.7rem; - text-transform: uppercase; + font-size: 1rem; + font-family: "Haffer"; + font-weight: 500; + letter-spacing: 0.05em; + margin: 0.7rem; + text-transform: uppercase; } #bittensor-img { - width: 80%; - display: block; - margin-left: auto; - margin-right: auto; + width: 80%; + display: block; + margin-left: auto; + margin-right: auto; } /* ALGOLIA SEARCH INPUT */ /* NAVBAR LINKS */ .navbar__item.navbar__link { - font-family: 'DM Mono', monospace; - color: var(--text-secondary); - font-size: 12px !important; - align-items: center; - letter-spacing: 0.6px; - margin-left: 32px; + font-family: "DM Mono", monospace; + color: var(--text-secondary); + font-size: 12px !important; + align-items: center; + letter-spacing: 0.6px; + margin-left: 32px; } @media (min-width: 997) { - .navbar__item.navbar__link { - display: flex; - } + .navbar__item.navbar__link { + display: flex; + } } .dropdown--right { - margin-right: auto; - margin-bottom: 0 !important; + margin-right: auto; + margin-bottom: 0 !important; } /* NAV TITLE */ .navbar__title.text--truncate { - font-size: 16px !important; - line-height: 27.2px !important; - font-weight: 400 !important; - font-family: "Haffer"; - letter-spacing: 0.32px; + font-size: 16px !important; + line-height: 27.2px !important; + font-weight: 400 !important; + font-family: "Haffer"; + letter-spacing: 0.32px; } /* Bread Crumb */ .breadcrumbs__item .breadcrumbs__link { - color: var(--text-secondary); - line-height: 130%; - letter-spacing: 0.6px; + color: var(--text-secondary); + line-height: 130%; + letter-spacing: 0.6px; } .breadcrumbs__item.breadcrumbs__item--active .breadcrumbs__link { - background: initial !important; - color: var(--text-primary); - font-family: 'DM Mono', monospace; + background: initial !important; + color: var(--text-primary); + font-family: "DM Mono", monospace; } /* Footer */ .footer__copyright.footer__copyright__custom .container { - max-width: 100%; + max-width: 100%; } @media (min-width: 1440px) { - .footer .container { - max-width: 100% !important; - padding: 0; - } + .footer .container { + max-width: 100% !important; + padding: 0; + } } -.theme-doc-sidebar-container>div>div { - width: 100% !important; +.theme-doc-sidebar-container > div > div { + width: 100% !important; } .theme-doc-sidebar-container nav { - padding: 16px 16px 16px 16px !important; - margin-top: 80px; + padding: 16px 16px 16px 16px !important; + margin-top: 80px; } .menu__link { - padding: 15px; - font-size: 15px !important; + padding: 15px; + font-size: 15px !important; } -.menu__link--sublist-caret::after{ - background: url('data:image/svg+xml;utf8,'); - transform: rotate(90deg); +.menu__link--sublist-caret::after { + background: url('data:image/svg+xml;utf8,'); + transform: rotate(90deg); } -.menu__caret::before{ - background: url('data:image/svg+xml;utf8,'); +.menu__caret::before { + background: url('data:image/svg+xml;utf8,'); } -.menu__caret{ - transform: rotate(270deg); - margin-right: 2px; +.menu__caret { + transform: rotate(270deg); + margin-right: 2px; } -.menu__list-item--collapsed .menu__link--sublist::after, .menu__list-item--collapsed.menu__caret::before{ - transform: rotateZ(0deg) !important; +.menu__list-item--collapsed .menu__link--sublist::after, +.menu__list-item--collapsed.menu__caret::before { + transform: rotateZ(0deg) !important; } .theme-doc-sidebar-menu.menu__list > li { - position: relative; + position: relative; } .theme-doc-sidebar-menu.menu__list > li::after { - content: ''; - background-position: 0 0; - background-image: linear-gradient(to right, var(--grey-900), 1.5px, transparent 1.5px); - background-repeat: repeat-x; - background-size: 6px; - display: block; - width: 100%; - height: 1.5px; - position: absolute; - bottom: 0px; - left: 0; + content: ""; + background-position: 0 0; + background-image: linear-gradient( + to right, + var(--grey-900), + 1.5px, + transparent 1.5px + ); + background-repeat: repeat-x; + background-size: 6px; + display: block; + width: 100%; + height: 1.5px; + position: absolute; + bottom: 0px; + left: 0; } .menu__list-item-collapsible { - position: relative; + position: relative; } .menu__list-item-collapsible::after { - content: ''; - background-position: 0 0; - background-image: linear-gradient(to right, var(--grey-900), 1.5px, transparent 1.5px); - background-repeat: repeat-x; - background-size: 6px; - display: block; - width: 100%; - height: 1.5px; - position: absolute; - bottom: 0px; - left: 0; -} - -.theme-doc-sidebar-item-link-level-2 { - position: relative; -} -.theme-doc-sidebar-item-link-level-2:not(:last-child)::after { - content: ''; - background-position: 0 0; - background-image: linear-gradient(to right, var(--grey-900), 1.5px, transparent 1.5px); - background-repeat: repeat-x; - background-size: 6px; - display: block; - width: 100%; - height: 1.5px; - position: absolute; - bottom: 0px; - left: 0; + content: ""; + background-position: 0 0; + background-image: linear-gradient( + to right, + var(--grey-900), + 1.5px, + transparent 1.5px + ); + background-repeat: repeat-x; + background-size: 6px; + display: block; + width: 100%; + height: 1.5px; + position: absolute; + bottom: 0px; + left: 0; +} + +.theme-doc-sidebar-item-link-level-2, +.theme-doc-sidebar-item-link-level-3 { + position: relative; +} +.theme-doc-sidebar-item-link-level-2:not(:last-child)::after, +.theme-doc-sidebar-item-link-level-3:not(:last-child)::after { + content: ""; + background-position: 0 0; + background-image: linear-gradient( + to right, + var(--grey-900), + 1.5px, + transparent 1.5px + ); + background-repeat: repeat-x; + background-size: 6px; + display: block; + width: 100%; + height: 1.5px; + position: absolute; + bottom: 0px; + left: 0; } .theme-doc-sidebar-menu.menu__list li { - margin: 0 !important; + margin: 0 !important; } .theme-doc-sidebar-menu.menu__list li > a { - height: 48px; + height: 48px; } .menu__link.menu__link--sublist.menu__link--sublist-caret { - height: 48px; + height: 48px; } .menu__link { - border-radius: 0 !important; - color: var(--ifm-navbar-item-color); - font-size: 12px !important; - font-family: 'DM Mono', monospace; - letter-spacing: 0.6px !important; + border-radius: 0 !important; + color: var(--ifm-navbar-item-color); + font-size: 12px !important; + font-family: "DM Mono", monospace; + letter-spacing: 0.6px !important; } [data-theme="dark"] .menu__link:hover { - color:var(--ifm-table-of-contents-text-active); - background-color: transparent; + color: var(--ifm-table-of-contents-text-active); + background-color: transparent; } [data-theme="dark"] .menu__list-item-collapsible { - background-color: transparent !important; - color:var(--ifm-table-of-contents-text-active) !important; + background-color: transparent !important; + color: var(--ifm-table-of-contents-text-active) !important; } .menu__link--active { - background-color: transparent !important; - color: var(--ifm-navbar-active-color) !important; - font-weight: 600; + background-color: transparent !important; + color: var(--ifm-navbar-active-color) !important; + font-weight: 600; } /* custom style for navbar - Change the Class name if you want stick with it (custom_algolia) */ -.custom__algolia__search__container_xfkw>div>div { - width: 353px !important; - min-width: 353px !important; - max-width: 353px !important; - height: 50px; +.custom__algolia__search__container_xfkw > div > div { + width: 353px !important; + min-width: 353px !important; + max-width: 353px !important; + height: 50px; } -.custom__algolia__search__container_xfkw>div { - width: 353px !important; - min-width: 353px !important; - max-width: 353px !important; - height: 50px; +.custom__algolia__search__container_xfkw > div { + width: 353px !important; + min-width: 353px !important; + max-width: 353px !important; + height: 50px; } @media screen and (min-width: 996px) { - .custom_algolia { - position: absolute; - left: 178px; - top: 200px; - } - .custom_algolia > div { - display: block !important; - } + .custom_algolia { + position: absolute; + left: 178px; + top: 200px; + } + .custom_algolia > div { + display: block !important; + } } - .search_container > div { - width: 268px !important; - height: 50px; + width: 268px !important; + height: 50px; } .navbar__inner { - align-content: center; + align-content: center; } .navbar__item { - padding: 0; + padding: 0; } .navbar__items--right { - gap: 0 32px !important; - height: 48px; + gap: 0 32px !important; + height: 48px; } /* right bar style */ .table-of-contents__link { - color: #5F6368; - font-family: 'DM Mono', monospace; - font-size: 0.75rem; - line-height: 130%; - letter-spacing: 0.6px; + color: #5f6368; + font-family: "DM Mono", monospace; + font-size: 0.75rem; + line-height: 130%; + letter-spacing: 0.6px; } .table-of-contents__link--active { - font-weight: bold; + font-weight: bold; } .table-of-contents.table-of-contents__left-border { - border: none !important; + border: none !important; } .table-of-contents.table-of-contents__left-border li { - margin: 0 !important; + margin: 0 !important; } .table-of-contents.table-of-contents__left-border li a { - padding: 10px 0; - padding-left: 15px; + padding: 10px 0; + padding-left: 15px; } .table-of-contents.table-of-contents__left-border ul { - padding: 0 !important; + padding: 0 !important; } -.table-of-contents>li>ul>li>a { - padding-left: 30px !important; - display: table !important; +.table-of-contents > li > ul > li > a { + padding-left: 30px !important; + display: table !important; } -.table-of-contents>li>ul>li>ul>li>a { - margin-left: 45px !important; +.table-of-contents > li > ul > li > ul > li > a { + margin-left: 45px !important; } .table-of-contents .table-of-contents__link:hover { - color: var(--ifm-table-of-contents-text-active) !important; + color: var(--ifm-table-of-contents-text-active) !important; } .container.padding-top--md { - position: relative; + position: relative; } -.container.padding-top--md>div>div:last-child { - padding-left: 1rem !important; +.container.padding-top--md > div > div:last-child { + padding-left: 1rem !important; } -.container.padding-top--md>div>div:first-child { - padding: 32px 32px 48px 56px !important; +.container.padding-top--md > div > div:first-child { + padding: 32px 32px 48px 56px !important; } /* */ @media screen and (max-width: 550px) { - .container.padding-top--md>div>div:first-child { - padding: 32px 32px 48px 32px !important; - } + .container.padding-top--md > div > div:first-child { + padding: 32px 32px 48px 32px !important; + } } .breadcrumbs:first-child svg { - top: 0px !important; - height: 1rem; - width: 1rem; + top: 0px !important; + height: 1rem; + width: 1rem; } .breadcrumbs__item--active span { - padding: 5px; + padding: 5px; } /* dropdown */ .dropdown { - z-index: 9999 !important; - padding-bottom: 10px; - margin-bottom: -10px !important; + z-index: 9999 !important; + padding-bottom: 10px; + margin-bottom: -10px !important; } .dropdown_menu_container { - position: relative; + position: relative; } .dropdown_menu_container li { - list-style: none; + list-style: none; } .dropdown_menu_container .dropdownNavbarItemNested { - position: absolute; - left: 100%; + position: absolute; + left: 100%; } .dropdown__menu { - padding: 0; - min-width: 200px !important; - border: 1px solid var(--ifm-navbar-border); - box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.08); - border-radius: var(--border-radius-border-radius-base, 4px); + padding: 0; + min-width: 200px !important; + border: 1px solid var(--ifm-navbar-border); + box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.08); + border-radius: var(--border-radius-border-radius-base, 4px); } -.dropdown--right .dropdown__menu{ - right: unset; +.dropdown--right .dropdown__menu { + right: unset; } .dropdown__menu .dropdown__link { - padding: 7px 20px !important; - border-radius: 0 !important; - margin: 0 !important; - cursor: pointer; - color: var(--text-secondary, #5F6368); - font-family: 'DM Mono', monospace; - font-size: 12px; - letter-spacing: 0.6px; - text-transform: uppercase; + padding: 7px 20px !important; + border-radius: 0 !important; + margin: 0 !important; + cursor: pointer; + color: var(--text-secondary, #5f6368); + font-family: "DM Mono", monospace; + font-size: 12px; + letter-spacing: 0.6px; + text-transform: uppercase; } /* Custom bottom border mixin */ .dropdown__menu > li { - position: relative; + position: relative; } .dropdown__menu > li:not(:last-child)::after { - content: ''; - background-position: 0 0; - background-image: linear-gradient(to right, var(--grey-900), 1.5px, transparent 1.5px); - background-repeat: repeat-x; - background-size: 6px; - display: block; - width: 100%; - height: 1.5px; - position: absolute; - bottom: 0; - left: 0; + content: ""; + background-position: 0 0; + background-image: linear-gradient( + to right, + var(--grey-900), + 1.5px, + transparent 1.5px + ); + background-repeat: repeat-x; + background-size: 6px; + display: block; + width: 100%; + height: 1.5px; + position: absolute; + bottom: 0; + left: 0; } .dropdown__link:hover { - background-color: var(--grey-100); + background-color: var(--grey-100); } .dropdown__menu ul { - padding-left: 15px !important; - height: 0; - overflow: hidden; - transition: all ease 0.3s !important; + padding-left: 15px !important; + height: 0; + overflow: hidden; + transition: all ease 0.3s !important; } @keyframes heightAnimation { - 0% { - height: 0px; - border-bottom: 1px dashed rgba(95, 99, 104, 1); - } + 0% { + height: 0px; + border-bottom: 1px dashed rgba(95, 99, 104, 1); + } - 100% { - border-bottom: 1px dashed rgba(95, 99, 104, 1); - height: 100%; - } + 100% { + border-bottom: 1px dashed rgba(95, 99, 104, 1); + height: 100%; + } } .dropdown__menu .active-nested-dropdown { - animation-name: heightAnimation; - animation-duration: 1s; - animation-fill-mode: both; + animation-name: heightAnimation; + animation-duration: 1s; + animation-fill-mode: both; } .dropdown__menu_nested_items { - border-bottom: 1px dashed rgba(95, 99, 104, 1) !important; + border-bottom: 1px dashed rgba(95, 99, 104, 1) !important; } .dropdown__menu li:last-child a { - border-bottom: 0 !important; + border-bottom: 0 !important; } .dropdown__menu li:last-child ul { - border-bottom: 0 !important; + border-bottom: 0 !important; } .dropdown__menu li:last-child { - border-bottom: 0 !important; + border-bottom: 0 !important; } .dropdown__menu ul li { - list-style: none !important; + list-style: none !important; } .dropdown__menu .has-dropdown { - display: flex; - width: 100% !important; - position: relative; + display: flex; + width: 100% !important; + position: relative; } .dropdown__menu .has-dropdown a { - width: 100% !important; + width: 100% !important; } .dropdown__menu .has-dropdown .arrow { - position: absolute; - right: 15px; - top: 12px; + position: absolute; + right: 15px; + top: 12px; } .navbar__item.dropdown a { - /* margin-top: 6px; */ - display: block; + /* margin-top: 6px; */ + display: block; } .navbar__item.dropdown a::after { - margin-left: 8px !important; - margin-bottom: 2px !important; + margin-left: 8px !important; + margin-bottom: 2px !important; } /* Dropdown caret */ .dropdown > .navbar__link::after { - border-width: 0.3em 0.3em 0; - top: 1px; + border-width: 0.3em 0.3em 0; + top: 1px; } /* breadcrumbs styles */ .breadcrumbs { - display: flex; - flex-wrap: wrap; + display: flex; + flex-wrap: wrap; } .breadcrumbs .breadcrumbs__item::after { - background: url("../../static//img/slice.svg"); - height: 15px; - background-size: cover; - background-repeat: no-repeat; + background: url("../../static//img/slice.svg"); + height: 15px; + background-size: cover; + background-repeat: no-repeat; } .breadcrumbs .breadcrumbs__item span { - padding: 0 !important; - display: table; + padding: 0 !important; + display: table; } .breadcrumbs .breadcrumbs__item { - display: flex; - align-items: center; + display: flex; + align-items: center; } .breadcrumbs .breadcrumbs__item:first-child { - display: flex !important; + display: flex !important; } .breadcrumbs .breadcrumbs__item .breadcrumbs__link { - padding: 0 !important; - font-size: 0.75rem; + padding: 0 !important; + font-size: 0.75rem; } .breadcrumbs__item--active span { - color: var(--ifm-breadcrumbs__item--active) !important; + color: var(--ifm-breadcrumbs__item--active) !important; } /* Feedback */ .feedback { - display: flex !important; - align-items: center; - gap: 0 20px; + display: flex !important; + align-items: center; + gap: 0 20px; } .feedback span { - font-weight: 400 !important; - text-transform: uppercase; - font-size: 0.7rem; - font-family: 'DM Mono', monospace; - letter-spacing:0.6; + font-weight: 400 !important; + text-transform: uppercase; + font-size: 0.7rem; + font-family: "DM Mono", monospace; + letter-spacing: 0.6; } .feedback .feelings { - display: flex; - align-items: center; - gap: 0 16px; + display: flex; + align-items: center; + gap: 0 16px; } .feeling { - width:32px; - height:32px; - border: 1px solid rgba(219,221,225,1); - border-radius:4px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; + width: 32px; + height: 32px; + border: 1px solid rgba(219, 221, 225, 1); + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; } .feedbackAndName { - display: flex; - align-items: center; - width: 100%; - justify-content: space-between; - margin-top: 80px; + display: flex; + align-items: center; + width: 100%; + justify-content: space-between; + margin-top: 80px; } .feeling-symbol { - cursor: pointer !important; + cursor: pointer !important; } .footer-line div { - position: absolute; - left: 0; - right: 0; - width: 100% !important; - border-top: 2px solid var(--ifm-navbar-border); - margin-top: -10px; - height: 110px; - z-index: 9 !important; - background-color: var(--ifm-footer-div-color); + position: absolute; + left: 0; + right: 0; + width: 100% !important; + border-top: 2px solid var(--ifm-navbar-border); + margin-top: -10px; + height: 110px; + z-index: 9 !important; + background-color: var(--ifm-footer-div-color); } /* pagination */ .pagination-nav { - display: flex !important; - justify-content: space-between; - z-index: 99 !important; - position: relative; + display: flex !important; + justify-content: space-between; + z-index: 99 !important; + position: relative; } .pagination-nav .pagination-nav__link { - max-width: 30% !important; + max-width: 30% !important; } -.pagination-nav:has(.pagination-nav__link:first-child.pagination-nav__link--next) { - justify-content: end; +.pagination-nav:has( + .pagination-nav__link:first-child.pagination-nav__link--next + ) { + justify-content: end; } - .table-of-contents.table-of-contents__left-border li a { - border-left: 1px solid var(--ifm-table-of-contents-border); + border-left: 1px solid var(--ifm-table-of-contents-border); } .table-of-contents.table-of-contents__left-border li a { - font-weight: 400; - color: var(--ifm-table-of-contents-text); + font-weight: 400; + color: var(--ifm-table-of-contents-text); } .table-of-contents__link--active { - border-left: 1px solid var(--ifm-table-of-contents-border-active) !important; - color: var(--ifm-table-of-contents-text-active) !important; + border-left: 1px solid var(--ifm-table-of-contents-border-active) !important; + color: var(--ifm-table-of-contents-text-active) !important; } .menu__link--sublist-caret.menu__link--active { - color: var(--ifm-menu__link--active) !important + color: var(--ifm-menu__link--active) !important; } .footer { - padding: 25px 30px !important; - background-color: var(--ifm-footer-bg) !important; + padding: 25px 30px !important; + background-color: var(--ifm-footer-bg) !important; } .footer .footer__copyright { - font-family: TTCommonsPro !important; - font-size: 14px !important; - text-transform: uppercase !important; - display: flex; - align-items: center; - justify-content: space-between; + font-family: TTCommonsPro !important; + font-size: 14px !important; + text-transform: uppercase !important; + display: flex; + align-items: center; + justify-content: space-between; } - .footer .footer__copyright a { - color: var(--ifm-footer-company-name-color) !important; + color: var(--ifm-footer-company-name-color) !important; } - /* Algolia Search */ .DocSearch { - position: fixed !important; - left: 0; - top: 0; - width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; + position: fixed !important; + left: 0; + top: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; } .DocSearch .DocSearch-Modal { - background-color: var(--ifm-algolia-bg) !important; - border-radius: 10px !important; - min-width: 40% !important; + background-color: var(--ifm-algolia-bg) !important; + border-radius: 10px !important; + min-width: 40% !important; } .DocSearch .DocSearch-Footer { - display: none !important; + display: none !important; } .DocSearch .DocSearch-Form { - background-color: var(--ifm-algolia-bg) !important; - box-shadow: inset 0 0 0 1px var(--ifm-algolia-border) !important; + background-color: var(--ifm-algolia-bg) !important; + box-shadow: inset 0 0 0 1px var(--ifm-algolia-border) !important; } .DocSearch .DocSearch-Form label { - color: var(--ifm-algolia-border) !important; + color: var(--ifm-algolia-border) !important; } .DocSearch .DocSearch-Form label svg { - width: 20px !important; - height: 20px !important; + width: 20px !important; + height: 20px !important; } .DocSearch .DocSearch-Form input::placeholder { - font-size: 16px !important; + font-size: 16px !important; } .DocSearch .DocSearch-Form input { - font-size: 16px !important; + font-size: 16px !important; } .DocSearch-Modal .DocSearch-Hit-source { - font-size: 14px !important; - text-transform: uppercase !important; - font-family: TTCommonsPro !important; + font-size: 14px !important; + text-transform: uppercase !important; + font-family: TTCommonsPro !important; } .DocSearch-Modal #docsearch-list li { - margin: 0 !important; + margin: 0 !important; } .navbar { - border-bottom: none !important; - box-shadow: none !important; + border-bottom: none !important; + box-shadow: none !important; } .navbar__logo { - margin-right: 13rem; + margin-right: 13rem; } - + /* Components design */ .alert { - position: relative; - border-left-width: 3px !important; - border-radius: 0 !important; - font-family: Haffer !important; - box-shadow: 0 !important; + position: relative; + border-left-width: 3px !important; + border-radius: 0 !important; + font-family: Haffer !important; + box-shadow: 0 !important; } .alert.alert--secondary { - background-color: var(--ifm-alert-secondary) !important; + background-color: var(--ifm-alert-secondary) !important; } .alert.alert--success { - background-color: var(--ifm-alert-success) !important; + background-color: var(--ifm-alert-success) !important; } .alert.alert--info { - background-color: var(--ifm-alert-info) !important; + background-color: var(--ifm-alert-info) !important; } .alert.alert--warning { - background-color: var(--ifm-alert-warning) !important; + background-color: var(--ifm-alert-warning) !important; } .alert.alert--warning span svg { - width: 18px !important; + width: 18px !important; } .alert.alert--danger { - background-color: var(--ifm-alert-danger) !important; + background-color: var(--ifm-alert-danger) !important; } .alert.alert--success svg, .alert.alert--info svg, .alert.alert--secondary svg { - width: 1.1rem !important; - height: 1.1rem !important; + width: 1.1rem !important; + height: 1.1rem !important; } blockquote { - border-left: 3px solid var(--ifm-blockquote-border) !important; + border-left: 3px solid var(--ifm-blockquote-border) !important; } -.language-bash>div span>span.token.plain { - font-family: FiraCode !important; +.language-bash > div span > span.token.plain { + font-family: FiraCode !important; } .theme-code-block div:first-child { - display: flex !important; - align-items: center; - gap: 0 10px !important; - font-family: FiraCode !important; + display: flex !important; + align-items: center; + gap: 0 10px !important; + font-family: FiraCode !important; } .theme-code-block div:first-child svg { - margin-top: -1px !important; + margin-top: -1px !important; } code { - font-family: FiraCode !important; + font-family: FiraCode !important; } -.tabs-container>ul { - display: flex !important; - gap: 0 5px; +.tabs-container > ul { + display: flex !important; + gap: 0 5px; } -.tabs-container>ul li { - border-radius: 5px !important; - font-weight: 400 !important; - letter-spacing: 2px; - font-size: 14px !important; - padding: 8px 10px !important; - padding-bottom: 5px !important; +.tabs-container > ul li { + border-radius: 5px !important; + font-weight: 400 !important; + letter-spacing: 2px; + font-size: 14px !important; + padding: 8px 10px !important; + padding-bottom: 5px !important; } -.tabs-container>ul li.tabs__item--active { - border-bottom: 0 !important; - background-color: var(--ifm-tab-container-active-bg) !important; - color: var(--ifm-tab-container-active-color) !important; +.tabs-container > ul li.tabs__item--active { + border-bottom: 0 !important; + background-color: var(--ifm-tab-container-active-bg) !important; + color: var(--ifm-tab-container-active-color) !important; } table { - background-color: transparent !important; - border-color: transparent !important; - border-spacing: 0 !important; - border: 0 !important; - width: 100% !important; - min-width: 100% !important; - display: table !important; + background-color: transparent !important; + border-color: transparent !important; + border-spacing: 0 !important; + border: 0 !important; + width: 100% !important; + min-width: 100% !important; + display: table !important; } table thead { - background-color: var(--ifm-table-header-bg) !important; + background-color: var(--ifm-table-header-bg) !important; } - table tr { - border-bottom: 1px dotted var(--ifm-table-tr-border) !important; - border: 0 !important; - border-spacing: 10px !important; - background-color: transparent !important; - background-image: linear-gradient(to right, var(--ifm-table-tr-border) 50%, transparent 50%); - background-size: 7px 1px; - background-repeat: repeat-x; - background-position: 0 bottom; + border-bottom: 1px dotted var(--ifm-table-tr-border) !important; + border: 0 !important; + border-spacing: 10px !important; + background-color: transparent !important; + background-image: linear-gradient( + to right, + var(--ifm-table-tr-border) 50%, + transparent 50% + ); + background-size: 7px 1px; + background-repeat: repeat-x; + background-position: 0 bottom; } table tbody tr:last-child { - border-bottom: 0 !important; - background-image: none !important; + border-bottom: 0 !important; + background-image: none !important; } table tbody { - background-color: transparent !important; + background-color: transparent !important; } table tr td, th { - border: 0 !important; - font-weight: 400 !important; + border: 0 !important; + font-weight: 400 !important; } table tr th { - color: var(--ifm-table-header-color) !important; - font-size: 15px !important; - /* text-align: center !important; */ - font-family: TTCommonsPro !important; - font-weight: 600 !important; + color: var(--ifm-table-header-color) !important; + font-size: 15px !important; + /* text-align: center !important; */ + font-family: TTCommonsPro !important; + font-weight: 600 !important; } table tr th:first-child { - text-align: start !important; + text-align: start !important; } table tr th:last-child { - text-align: start !important; + text-align: start !important; } table tr td { - color: var(--ifm-table-body-color) !important; - font-size: 14px !important; + color: var(--ifm-table-body-color) !important; + font-size: 14px !important; } table tr td:first-child { - font-weight: 400 !important; + font-weight: 400 !important; } hr { - background-color: transparent !important; - background-image: linear-gradient(to right, var(--ifm-hr) 10%, transparent 30%); - background-size: 5px 7px; - background-repeat: repeat-x; - background-position: 0 bottom; + background-color: transparent !important; + background-image: linear-gradient( + to right, + var(--ifm-hr) 10%, + transparent 30% + ); + background-size: 5px 7px; + background-repeat: repeat-x; + background-position: 0 bottom; } ol:not([class]) li { - font-size: 16px !important; - font-weight: 400 !important; - font-family: "Haffer"; + font-size: 16px !important; + font-weight: 400 !important; + font-family: "Haffer"; } ul.dashed_ul { - list-style-type: none !important; - padding: 0 !important; - padding-left: 25px !important; + list-style-type: none !important; + padding: 0 !important; + padding-left: 25px !important; } -ul.dashed_ul>li { - font-size: 16px !important; - position: relative; - font-weight: 400 !important; +ul.dashed_ul > li { + font-size: 16px !important; + position: relative; + font-weight: 400 !important; } -ul.dashed_ul>li::before { - content: "" !important; - display: block; - width: 8px !important; - background-color: var(--ifm-ul) !important; - height: 1px !important; - margin-top: 12px !important; - margin-right: 10px !important; - position: absolute; - left: -15px; +ul.dashed_ul > li::before { + content: "" !important; + display: block; + width: 8px !important; + background-color: var(--ifm-ul) !important; + height: 1px !important; + margin-top: 12px !important; + margin-right: 10px !important; + position: absolute; + left: -15px; } - -p>a>img[loading="lazy"] { - width: 100% !important; +p > a > img[loading="lazy"] { + width: 100% !important; } .open_grepper_editor { - display: none !important; + display: none !important; } - -.theme-doc-sidebar-menu.menu__list li:first-child>div { - display: none !important; +.theme-doc-sidebar-menu.menu__list li:first-child > div { + display: none !important; } .navbar .navbar__inner .navbar__items .navbar__brand { - display: flex; + display: flex; } .lastEdit { - width: 100%; - text-align: right; - font-size: 12px !important; - font-family: TTCommonsPro !important; - color: #5f6368; - position: absolute !important; - top: -15px !important; + width: 100%; + text-align: right; + font-size: 12px !important; + font-family: TTCommonsPro !important; + color: #5f6368; + position: absolute !important; + top: -15px !important; } .navbar.navbar--fixed-top { - margin-bottom: 0 !important; + margin-bottom: 0 !important; } main article { - position: relative !important; + position: relative !important; } main article a { - text-decoration: underline !important; + text-decoration: underline !important; } footer .container.container-fluid { - margin: 0 !important; - max-width: 100% !important; + margin: 0 !important; + max-width: 100% !important; } #docsearch-list { - border: 2px solid var(--ifm-doc-search-border-color) !important; - border-radius: 5px !important; + border: 2px solid var(--ifm-doc-search-border-color) !important; + border-radius: 5px !important; } #docsearch-list li { - padding: 0 !important; + padding: 0 !important; } #docsearch-list li a { - box-shadow: none !important; - border-bottom: 1px dashed var(--ifm-doc-search-border-color) !important; - background-color: transparent !important; + box-shadow: none !important; + border-bottom: 1px dashed var(--ifm-doc-search-border-color) !important; + background-color: transparent !important; } #docsearch-list li:last-child a { - border-bottom: 0 !important; + border-bottom: 0 !important; } #docsearch-list li a .DocSearch-Hit-icon svg { - color: var(--ifm-dock-search-svg-color) !important; + color: var(--ifm-dock-search-svg-color) !important; } .DocSearch-Hits .DocSearch-Hit-source { - font-weight: 600 !important; - color: var(--ifm-doc-search-title-color) !important; - font-size: 13px !important; - letter-spacing: 1px !important; - background: var(--ifm-doc-search-title-bg) !important; + font-weight: 600 !important; + color: var(--ifm-doc-search-title-color) !important; + font-size: 13px !important; + letter-spacing: 1px !important; + background: var(--ifm-doc-search-title-bg) !important; } -.DocSearch-Hit[aria-selected=true] a { - background-color: var(--ifm-dock-search-active-a-bg) !important; - border-radius: 0 !important; +.DocSearch-Hit[aria-selected="true"] a { + background-color: var(--ifm-dock-search-active-a-bg) !important; + border-radius: 0 !important; } -.DocSearch-Hit[aria-selected=true] a .DocSearch-Hit-title { - font-weight: bold !important; - color: var(--ifm-dock-search-active-a-color) !important; +.DocSearch-Hit[aria-selected="true"] a .DocSearch-Hit-title { + font-weight: bold !important; + color: var(--ifm-dock-search-active-a-color) !important; } -.DocSearch-Hit[aria-selected=true] a .DocSearch-Hit-title mark { - font-weight: bold !important; - color: var(--ifm-dock-search-active-a-color) !important; - background-color: rgba(233, 244, 164, 1) !important; - color: #000000 !important; +.DocSearch-Hit[aria-selected="true"] a .DocSearch-Hit-title mark { + font-weight: bold !important; + color: var(--ifm-dock-search-active-a-color) !important; + background-color: rgba(233, 244, 164, 1) !important; + color: #000000 !important; } -.DocSearch-Hit[aria-selected=true] a .DocSearch-Hit-path { - font-weight: 400 !important; - color: var(--ifm-dock-search-active-a-color) !important; +.DocSearch-Hit[aria-selected="true"] a .DocSearch-Hit-path { + font-weight: 400 !important; + color: var(--ifm-dock-search-active-a-color) !important; } -.DocSearch-Hit[aria-selected=true] a .DocSearch-Hit-path mark { - font-weight: 600 !important; - color: var(--ifm-dock-search-active-a-color) !important; - background-color: rgba(233, 244, 164, 1) !important; - color: #000000 !important; +.DocSearch-Hit[aria-selected="true"] a .DocSearch-Hit-path mark { + font-weight: 600 !important; + color: var(--ifm-dock-search-active-a-color) !important; + background-color: rgba(233, 244, 164, 1) !important; + color: #000000 !important; } -.DocSearch-Hit[aria-selected=true] a .DocSearch-Hit-Tree { - color: var(--docsearch-muted-color) !important; +.DocSearch-Hit[aria-selected="true"] a .DocSearch-Hit-Tree { + color: var(--docsearch-muted-color) !important; } - [data-theme="dark"] { - .theme-doc-sidebar-menu li:first-child>div>div { - border: 1px solid #282a2d !important; - } + .theme-doc-sidebar-menu li:first-child > div > div { + border: 1px solid #282a2d !important; + } } [data-theme="light"] { - .menu__link--sublist-caret.menu__link--active { - font-weight: 400; - } + .menu__link--sublist-caret.menu__link--active { + font-weight: 400; + } - .footer__copyright.footer__copyright__custom { - color: var(--grey-100) !important; - } + .footer__copyright.footer__copyright__custom { + color: var(--grey-100) !important; + } } @media screen and (max-width: 1310px) { - .navbar__inner .navbar__items--right a:nth-child(3) { - margin-right: 20px !important; - } + .navbar__inner .navbar__items--right a:nth-child(3) { + margin-right: 20px !important; + } } @media screen and (max-width: 996px) { - .navbar__inner .navbar__items:first-child div { - right: 0 !important; - } + .navbar__inner .navbar__items:first-child div { + right: 0 !important; + } - .navbar.navbar--fixed-top { - padding: 10px 15px !important; - } + .navbar.navbar--fixed-top { + padding: 10px 15px !important; + } - .navbar__inner .search_container div:last-child { - margin-right: 0px !important; - } + .navbar__inner .search_container div:last-child { + margin-right: 0px !important; + } - .theme-doc-sidebar-menu.menu__list li:first-child>div { - display: block !important; - } + .theme-doc-sidebar-menu.menu__list li:first-child > div { + display: block !important; + } - .navbar__inner .search_container { - width: 100%; - } + .navbar__inner .search_container { + width: 100%; + } - .navbar__toggle.clean-btn { - margin-bottom: 5px; - } + .navbar__toggle.clean-btn { + margin-bottom: 5px; + } - .navbar__items.navbar__items--right { - display: none; - } + .navbar__items.navbar__items--right { + display: none; + } } - @media screen and (max-width: 600px) { + .pagination-nav .pagination-nav__link { + max-width: 45% !important; + width: 100% !important; + padding: 0 !important; + } - .pagination-nav .pagination-nav__link { - max-width: 45% !important; - width: 100% !important; - padding: 0 !important; - } + .footer-line div { + height: 2px !important; + } - .footer-line div { - height: 2px !important; - } + .footer { + padding: 20px 10px !important; + } - .footer { - padding: 20px 10px !important; - } + .footer .footer__copyright { + gap: 0 20px !important; + } - .footer .footer__copyright { - gap: 0 20px !important; - } - - .navbar { - padding: 5px 20px !important; - } + .navbar { + padding: 5px 20px !important; + } } @media screen and (max-width: 550px) { - .pagination-nav.docusaurus-mt-lg { - margin-top: 80px !important; - } + .pagination-nav.docusaurus-mt-lg { + margin-top: 80px !important; + } } @media screen and (max-width: 500px) { - .navbar-sidebar { - width: 100% !important; - } + .navbar-sidebar { + width: 100% !important; + } - .navbar-sidebar__item:last-child { - width: 100% !important; - } + .navbar-sidebar__item:last-child { + width: 100% !important; + } - .pagination-nav .pagination-nav__link { - max-width: 489 !important; - } + .pagination-nav .pagination-nav__link { + max-width: 489 !important; + } - .navbar-sidebar__item menu{ - width: 100% !important; - } - + .navbar-sidebar__item menu { + width: 100% !important; + } } - @media screen and (max-width: 420px) { + .navbar { + padding: 5px 10px !important; + } - .navbar { - padding: 5px 10px !important; - } - - .footer { - padding: 20px 0 !important; - } + .footer { + padding: 20px 0 !important; + } } -.pagination-nav__link--next > .pagination-nav__label{ - text-align: right; +.pagination-nav__link--next > .pagination-nav__label { + text-align: right; } .pagination-nav__link--next > .pagination-nav__sublabel { - font-family: 'DM Mono', monospace; - position: relative; - padding-right: 12px; - text-align: right; + font-family: "DM Mono", monospace; + position: relative; + padding-right: 12px; + text-align: right; } .pagination-nav__link--next > .pagination-nav__sublabel::before { - content: ""; - position: absolute; - right: 0px; - top: 4.5px; - width: 0; - height: 0; - border-top: 4px solid transparent; /* Adjust the size of the arrow */ - border-bottom: 4px solid transparent; /* Adjust the size of the arrow */ - border-left: 6px solid rgb(82, 88, 96); /* Adjust the size and color of the arrow */ + content: ""; + position: absolute; + right: 0px; + top: 4.5px; + width: 0; + height: 0; + border-top: 4px solid transparent; /* Adjust the size of the arrow */ + border-bottom: 4px solid transparent; /* Adjust the size of the arrow */ + border-left: 6px solid rgb(82, 88, 96); /* Adjust the size and color of the arrow */ } .pagination-nav__link--prev > .pagination-nav__sublabel { - font-family: 'DM Mono', monospace; - position: relative; - padding-left: 12px; + font-family: "DM Mono", monospace; + position: relative; + padding-left: 12px; } .pagination-nav__link--prev > .pagination-nav__sublabel::before { - content: ""; - position: absolute; - left: 0px; - top: 4.5px; - width: 0; - height: 0; - border-top: 4px solid transparent; - border-bottom: 4px solid transparent; - border-right: 6px solid rgb(82, 88, 96); + content: ""; + position: absolute; + left: 0px; + top: 4.5px; + width: 0; + height: 0; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-right: 6px solid rgb(82, 88, 96); } .important { - background: none; + background: none; } diff --git a/src/theme/DocBreadcrumbs/index.js b/src/theme/DocBreadcrumbs/index.js index 747304797e..e2c9fb82b8 100644 --- a/src/theme/DocBreadcrumbs/index.js +++ b/src/theme/DocBreadcrumbs/index.js @@ -2,10 +2,12 @@ import React from 'react'; import clsx from 'clsx'; import {ThemeClassNames} from '@docusaurus/theme-common'; import { - useSidebarBreadcrumbs, useHomePageRoute, } from '@docusaurus/theme-common/internal'; -import { useDoc } from "@docusaurus/theme-common/internal"; +import { + useDoc, + useSidebarBreadcrumbs +} from '@docusaurus/plugin-content-docs/client'; import Link from '@docusaurus/Link'; import {translate} from '@docusaurus/Translate'; import HomeBreadcrumbItem from '@theme/DocBreadcrumbs/Items/Home'; diff --git a/src/theme/DocItem/Content/index.js b/src/theme/DocItem/Content/index.js index e9e78dbbd8..4dfeae7cea 100644 --- a/src/theme/DocItem/Content/index.js +++ b/src/theme/DocItem/Content/index.js @@ -1,7 +1,7 @@ import React from "react"; import clsx from "clsx"; import { ThemeClassNames } from "@docusaurus/theme-common"; -import { useDoc } from "@docusaurus/theme-common/internal"; +import { useDoc } from "@docusaurus/plugin-content-docs/client"; import Heading from "@theme/Heading"; import MDXContent from "@theme/MDXContent"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; diff --git a/src/theme/DocItem/Footer/index.js b/src/theme/DocItem/Footer/index.js index ca6a8df43b..3323e1a1db 100644 --- a/src/theme/DocItem/Footer/index.js +++ b/src/theme/DocItem/Footer/index.js @@ -1,7 +1,7 @@ import React, { useEffect, useState } from "react"; import clsx from "clsx"; import { ThemeClassNames } from "@docusaurus/theme-common"; -import { useDoc } from "@docusaurus/theme-common/internal"; +import { useDoc } from "@docusaurus/plugin-content-docs/client"; import TagsListInline from "@theme/TagsListInline"; import { track } from "@vercel/analytics"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; diff --git a/src/theme/DocItem/Layout/index.js b/src/theme/DocItem/Layout/index.js index e5c43e6761..beaa6d9acd 100644 --- a/src/theme/DocItem/Layout/index.js +++ b/src/theme/DocItem/Layout/index.js @@ -1,7 +1,7 @@ import React from 'react'; import clsx from 'clsx'; import { useWindowSize } from '@docusaurus/theme-common'; -import { useDoc } from '@docusaurus/theme-common/internal'; +import { useDoc } from '@docusaurus/plugin-content-docs/client'; import DocItemPaginator from '@theme/DocItem/Paginator'; import DocVersionBanner from '@theme/DocVersionBanner'; import DocVersionBadge from '@theme/DocVersionBadge'; @@ -10,7 +10,7 @@ import DocItemTOCMobile from '@theme/DocItem/TOC/Mobile'; import DocItemTOCDesktop from '@theme/DocItem/TOC/Desktop'; import DocItemContent from '@theme/DocItem/Content'; import DocBreadcrumbs from '@theme/DocBreadcrumbs'; -import Unlisted from '@theme/Unlisted'; +import Unlisted from "@theme/ContentVisibility/Unlisted"; import styles from './styles.module.css'; /** * Decide if the toc should be rendered, on mobile or desktop viewports diff --git a/src/theme/DocSidebarItem/Category/index.js b/src/theme/DocSidebarItem/Category/index.js index 2f3115eead..3309aee7b0 100644 --- a/src/theme/DocSidebarItem/Category/index.js +++ b/src/theme/DocSidebarItem/Category/index.js @@ -11,12 +11,12 @@ import { isActiveSidebarItem, findFirstSidebarItemLink, useDocSidebarItemsExpandedState, - isSamePath, -} from '@docusaurus/theme-common/internal'; +} from '@docusaurus/plugin-content-docs/client'; import Link from '@docusaurus/Link'; import {translate} from '@docusaurus/Translate'; import useIsBrowser from '@docusaurus/useIsBrowser'; import DocSidebarItems from '@theme/DocSidebarItems'; +import { isSamePath } from '@docusaurus/theme-common/internal'; // If we navigate to a category and it becomes active, it should automatically // expand itself function useAutoExpandActiveCategory({isActive, collapsed, updateCollapsed}) { diff --git a/src/theme/DocSidebarItem/Link/index.js b/src/theme/DocSidebarItem/Link/index.js index 591f55c9be..112cd2e36d 100644 --- a/src/theme/DocSidebarItem/Link/index.js +++ b/src/theme/DocSidebarItem/Link/index.js @@ -1,7 +1,7 @@ import React from 'react'; import clsx from 'clsx'; import { ThemeClassNames } from '@docusaurus/theme-common'; -import { isActiveSidebarItem } from '@docusaurus/theme-common/internal'; +import { isActiveSidebarItem } from '@docusaurus/plugin-content-docs/client'; import Link from '@docusaurus/Link'; import isInternalUrl from '@docusaurus/isInternalUrl'; import IconExternalLink from '@theme/Icon/ExternalLink'; diff --git a/src/theme/DocSidebarItems/index.js b/src/theme/DocSidebarItems/index.js index 9a73944e27..86b65ea291 100644 --- a/src/theme/DocSidebarItems/index.js +++ b/src/theme/DocSidebarItems/index.js @@ -1,9 +1,9 @@ import React, {memo} from 'react'; import { DocSidebarItemsExpandedStateProvider, - useVisibleSidebarItems, -} from '@docusaurus/theme-common/internal'; + useVisibleSidebarItems } from '@docusaurus/plugin-content-docs/client'; import DocSidebarItem from '@theme/DocSidebarItem'; + function DocSidebarItems({items, ...props}) { const visibleItems = useVisibleSidebarItems(items, props.activePath); return ( diff --git a/static/img/docs/commit-reveal-v4-sequence.png b/static/img/docs/commit-reveal-v4-sequence.png new file mode 100644 index 0000000000..a922f2a2b3 Binary files /dev/null and b/static/img/docs/commit-reveal-v4-sequence.png differ diff --git a/static/img/docs/commit-reveal-v4.svg b/static/img/docs/commit-reveal-v4.svg new file mode 100644 index 0000000000..df0aceabb8 --- /dev/null +++ b/static/img/docs/commit-reveal-v4.svg @@ -0,0 +1 @@ +Commit Reveal v4 (tempo set to 100 blocks)Commit Reveal v4 (tempo set to 100 blocks)ValidatorValidatorValidatorValidatorValidatorValidatorValidatorValidatorChain storageChain storageChain storageChain storageChain storageChain storageChain storageChain storageCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsValidatorValidatorValidatorValidatorValidatorValidatorValidatorValidatorSubtensorSubtensorSubtensorSubtensorSubtensorSubtensorSubtensorSubtensorChain storageChain storageChain storageChain storageChain storageChain storageChain storageChain storageCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsYumaYumaYumaYumaYumaYumaYumaYumaDrandDrandDrandDrandDrandDrandDrandDrandValidatorValidatorSubtensorSubtensorChain storageChain storageCurrent weightsCurrent weightsYumaYumaDrandDrandValidatorValidatorValidatorValidatorValidatorValidatorValidatorValidatorChain storageChain storageChain storageChain storageChain storageChain storageChain storageChain storageCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsCurrent weightsTempo 10 start[block 1000]tempo beginsevaluateminers[block 1005]drand pulsereveal weightsweights waitingfor epoch[block 1090-1099]commit weightsstoreconcealmentperiodTempo 10 epoch[block 1100]get weightsrun epochTempo 11 start[block 1100]tempo beginsevaluateminers[block 1105]drand pulsereveal weightsweights waitingfor epoch[block 1190-1199]commit weightsstoreconcealmentperiodTempo 11 epoch[block 1200]get weightsrun epochTempo 12 start[block 1200]tempo beginsevaluateminers[block 1205]drand pulsereveal weightsweights waitingfor epoch[block 1290-1299]commit weightsstoreconcealmentperiod \ No newline at end of file diff --git a/static/img/docs/position-dashboard1.png b/static/img/docs/position-dashboard1.png new file mode 100644 index 0000000000..51e0a82b41 Binary files /dev/null and b/static/img/docs/position-dashboard1.png differ diff --git a/static/img/docs/weight-copy.svg b/static/img/docs/weight-copy.svg new file mode 100644 index 0000000000..380f508ddc --- /dev/null +++ b/static/img/docs/weight-copy.svg @@ -0,0 +1 @@ +Weight Copying (tempo set to 100 blocks)Weight Copying (tempo set to 100 blocks)ValidatorValidatorValidatorCurrent weightsValidatorValidatorSubtensorSubtensorCurrent weightsCurrent weightsYumaYumaWeight copierWeight copierValidatorValidatorSubtensorSubtensorCurrent weightsCurrent weightsYumaYumaWeight copierWeight copierValidatorValidatorValidatorCurrent weightsTempo 10 start[block 1000]tempo beginsevaluateminers[block 1090-1099]set weightsstore weightsweights waitingfor epochget weightscalculatethe stake-weightedaverage of weights[block 1090-1099]set weightsstore weightsTempo 10 epoch[block 1100]get weightsrun epochTempo 11 start[block 1100]tempo beginsevaluateminers \ No newline at end of file diff --git a/static/python-api/html/.buildinfo b/static/python-api/html/.buildinfo index d68be7cc29..03af23f641 100644 --- a/static/python-api/html/.buildinfo +++ b/static/python-api/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 5db28c7b8cd6c3b493481038c43232af +config: 596373974aba17ed1e8dbc63aa6bcbab tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/static/python-api/html/_modules/async_substrate_interface/errors.html b/static/python-api/html/_modules/async_substrate_interface/errors.html index 735378d97d..7e74ed35fa 100644 --- a/static/python-api/html/_modules/async_substrate_interface/errors.html +++ b/static/python-api/html/_modules/async_substrate_interface/errors.html @@ -149,7 +149,6 @@
  • API Reference