Overview
Mana is an Express.js transaction relayer service that enables gasless voting and automated proposal execution for Snapshot X governance. It handles cross-chain messaging between Layer 1 (Ethereum) and Layer 2 (Starknet) networks.Mana allows users to vote and create proposals without paying gas fees by relaying transactions on their behalf.
Key Features
Gasless Voting
Submit votes without paying transaction fees
Cross-Chain Messaging
Bridge governance actions between L1 and L2
Automated Execution
Execute proposals when conditions are met
Multi-Network Support
Support for Ethereum, Starknet, and multiple chains
Quick Start
Prerequisites
- Node.js >= 22.6
- PostgreSQL database
- Wallet with sufficient funds for gas on supported networks
Installation
Environment Configuration
Copy.env.example to .env and configure:
.env.example
Start Development Server
- Run database migrations
- Start the Express server
- Begin monitoring for registered transactions and proposals
PORT in src/constants.ts
Package Scripts
Frompackage.json:
Key Commands
Architecture
JSON-RPC Endpoints
Mana exposes two main RPC endpoints:apps/mana/src/index.ts
Background Loops
Three continuous processes monitor and execute governance actions:apps/mana/src/index.ts
How It Works
Gasless Voting Flow
- User submits vote to Mana via JSON-RPC
- Mana validates the vote signature
- Mana relays the transaction to the blockchain
- User pays no gas - Mana’s wallet covers the cost
Cross-Chain Execution (L1 ↔ L2)
L2 → L1 (Starknet to Ethereum):- Proposal passes on Starknet
- Execution hash committed to L1
- Mana monitors Starknet Core contract on Ethereum
- When message arrives, Mana executes on L1
- Action triggered on Ethereum
- Message sent to Starknet Core
- Mana relays message to Starknet
- Execution occurs on L2
Automated Proposal Execution
Mana continuously monitors proposals and:- Checks if voting period has ended
- Verifies quorum and threshold requirements
- Automatically executes passed proposals
- Handles execution failures and retries
API Endpoints
Health Check
Debug Endpoints
Wallet Management
Mana manages multiple wallets derived fromWALLET_SECRET:
Database Schema
Mana uses PostgreSQL with Knex.js migrations to track:- Registered transactions awaiting execution
- Proposal execution status
- Cross-chain message tracking
- Execution attempts and results
Running Migrations
Migrations run automatically onyarn dev and yarn start, or manually:
Supported Networks
EVM Networks
Configured viaethHandlers indexed by chain ID:
- Base (8453)
- Sepolia (11155111)
- Additional networks as configured
Starknet Networks
- Starknet Mainnet
- Starknet Sepolia
Dependencies
Key dependencies frompackage.json:
Security Considerations
Logging
Mana uses Pino for structured logging:Monitoring
Health Checks
Monitor the root endpoint:Wallet Balances
Regularly check relayer wallet balances:Database Monitoring
Monitor:- Transaction queue depth
- Failed execution attempts
- Average execution time
- Database connection pool usage
Error Handling
Mana includes comprehensive error handling:apps/mana/src/index.ts
Production Deployment
-
Build the application:
- Set production environment variables
- Fund relayer wallets with sufficient gas tokens
-
Start the service:
- Set up monitoring and alerts
Integration with UI
The UI submits gasless transactions to Mana:Troubleshooting
Service won’t start
- Verify
WALLET_SECRETis set - Check database connection (
DATABASE_URL) - Ensure PostgreSQL is running
Transactions not executing
- Check wallet balances
- Verify RPC endpoint connectivity
- Review logs for errors
- Check database for stuck transactions
High memory usage
- Use
/debug/heapdumpendpoint to analyze - Review background loop performance
- Check for memory leaks in long-running processes
Repository
Source code: snapshot-labs/sx-monorepo Package directory:apps/mana