This project manages a liquidity mining system for the Bittensor ecosystem, where token holders vote on liquidity pools and validators process these votes to set miner weights on subnet 77.
The system operates through a server (https://77.creativebuilds.io
) that handles:
- Vote Collection: Token holders submit weighted votes for liquidity pools
- Weight Calculation: The server processes votes and calculates final miner weights
- Validator Integration: Validators fetch weights from the server and set them on-chain
- Vote Management: Collects and stores user votes with Ed25519 signature verification
- Weight Calculation: Processes votes and calculates final miner weights based on token holdings and liquidity positions
- API Endpoints: Provides RESTful API for all system operations
- Weight Fetching: Retrieves calculated weights from the server
- On-chain Updates: Sets miner weights on the Bittensor network
- Version Management: Includes automatic version checking and update capabilities
- Voting: Submit weighted votes for liquidity pools
- Registration: Link Bittensor hotkeys to Ethereum addresses
- Pool Management: View current pool information and voting status
- Install dependencies (Bun is the primary runtime)
bun install
- Set up environment variables
cp .env.example .env
# Fill in the required variables (see Environment section below)
- Query current pool weights
bun run pools
Token holders can vote on which liquidity pools should receive weight in the system.
What you can do:
- Vote on pools: Submit weighted votes for active liquidity pools
- Check pool status: View current pool weights and rankings
- Monitor your voting power: Track your influence based on token balance
Key command:
# Submit votes for pools (weights must sum to 10000)
just vote
# Retract all votes (send empty allocation)
just vote --retract
Setup required:
HOLDER_COLDKEY
in.env
(your Bittensor coldkey for signing votes)
Validators read weights from the server and periodically push them to subnet 77.
What you can do:
- Run weight calculation: Process votes and compute final miner weights
- Submit weights to subnet: Push calculated weights to the Bittensor network
- Monitor system health: Track voting patterns and pool performance
Key commands:
# Start the validator (processes votes and submits weights)
just validate
# Run in test mode (compute weights but skip submission)
TEST_MODE=true just validate
# Enable verbose logging
LOG=true just validate
Setup required:
VALIDATOR_HOTKEY_URI
in.env
(your validator hotkey)THEGRAPH_API_KEY
in.env
(for Uniswap V3 LP data)
Miners provide liquidity to pools and can register their addresses to participate in the system.
What you can do:
- Register your address: Link your Bittensor public key to an EVM address
- Provide liquidity: Add liquidity to pools to earn rewards
- Monitor earnings: Track your pool performance and rewards
Key commands:
# Register your Bittensor public key with an EVM address
just register
# Check your registration status
bunx tsx scripts/check-key.ts
# View pool analytics and your position
bun run pools
Setup required:
MINER_HOTKEY
in.env
(your Bittensor hotkey)ETH_KEY
in.env
(your Ethereum private key)- Bittensor wallet with stake on subnet 77
Script | Purpose | Usage |
---|---|---|
create-key.ts |
Generate or import an EVM keypair and derive the corresponding SS58 address. Stores everything in .keys/ and can update .env . |
bunx tsx scripts/create-key.ts |
register.ts |
Link a Bittensor hotkey → EVM address via the server. Requires MINER_HOTKEY and ETH_KEY environment variables. |
just register |
vote.ts |
Interactive pool-weight voting. Searches and selects pools, then submits weighted votes that sum to 10000. Supports retracting votes with --retract flag. |
just vote |
pools.ts |
Display current pool information from the API including pool details, voter information, and alpha token balances. | just pools |
Run scripts with
LOG=true
to enable verbose logging where available.
The project uses just
as a command runner for common tasks:
Command | Description |
---|---|
just register |
Register a Bittensor public key with an EVM address |
just vote |
Submit votes for liquidity pools |
just validate |
Start the validator to process votes and submit weights |
Create a .env
file in the project root. The most important keys are:
# VALIDATOR ONLY: this can be a private key, URI, or mnemonic
# Used to set weights on chain
VALIDATOR_HOTKEY_URI=
# VALIDATOR ONLY: used to fetch uniswap v3 LP positions for miners
THEGRAPH_API_KEY=
# VALIDATOR ONLY: set to 'true' to run in test mode (weights saved to files, not submitted to network)
TEST_MODE=false
# VOTER ONLY: hex string starting with 0x
# Used to sign votes in vote.ts script
HOLDER_COLDKEY=
# MINER ONLY: hex string starting with 0x
# Used for hotkey in register.ts script
MINER_HOTKEY=
# MINER ONLY: ethereum private key hex string
# Used for ethereum wallet in register.ts script
ETH_KEY=
# VALIDATOR ONLY: OPT-IN: will automatically git pull when a new minor version is live
AUTO_UPDATE_ENABLED=false
Everything else has sensible defaults or is only required for specific tasks.
• The Graph: Log in to Subgraph Studio → API Keys in the sidebar → Create API Key → copy the generated token. See the official guide for details (docs).
The server provides the following key endpoints:
/updateVotes
: Submit or update votes for liquidity pools (includes cooldown management)/claimAddress
: Register Ethereum addresses for Bittensor hotkeys/weights
: Retrieve final calculated miner weights/pools
: Get current pool information and voting status/positions
: Fetch Uniswap V3 liquidity positions for miners with USD values/voteCooldown/:address
: Check voting cooldown status for an address/voteHistory/:address
: View complete vote change history for an address/userVotes/:address
: Get current votes for a specific address/allVotes
: Retrieve all votes with token-based weight multipliers/allHolders
: Get all token holders and their balances/allMiners
: List all subnet miners with linked Ethereum addresses/ping
: Version compatibility check for validators
The system includes sophisticated cooldown management to prevent gaming:
- Base cooldown: 72 minutes after vote changes
- Progressive system: Cooldown doubles for frequent changes (72m → 144m → 288m → 576m)
- Maximum cap: 8 hours maximum cooldown
- Reset mechanism: 24 hours of inactivity resets to base cooldown
- First-time voting: No cooldown for new voters
Liquidity positions now include:
- Current token amounts and USD values
- CoinGecko price integration
- Automatic filtering of inactive positions
- Real-time emission calculations
- Complete audit trail of all vote changes
- Detailed cooldown timing information
- Change counting and progressive cooldown tracking
See validator/api-server-docs.json
for complete API documentation.
The validator includes automatic version checking and update capabilities:
AUTO_UPDATE_ENABLED
: Set totrue
to enable automatic updates (default:false
)TEST_MODE
: Set totrue
to run in test mode (default:false
)LOG
: Set totrue
to enable console logging (default:false
)
- Periodic Version Checks: Every 30 minutes, the validator pings the server to check version compatibility
- 12-Hour Timeout: If version incompatibility persists for 12 hours, the validator automatically shuts down
- Auto-Update: When enabled, automatically pulls latest changes and restarts
- Persistent Warnings: Version warnings are saved locally and checked on startup
- Graceful Degradation: Version issues don't immediately stop the validator, allowing time for updates
PRs welcome – especially on optimisation of the weight formula, better docs, or additional scripts.
MIT © 2025 creativebuilds