# Bisq Nostr Bot A Nostr bot that queries a local Bisq daemon and provides marketplace information to Nostr users. ## Features - **Multi-relay support**: Connect to multiple Nostr relays in parallel - **Marketplace queries**: Get top 10 offers by price for any currency pair - **Market statistics**: Publish daily market stats and trends - **Mention-based interaction**: Users mention the bot with commands - **Async architecture**: Non-blocking, efficient event processing - **Error handling**: Graceful error messages returned to users ## Architecture ### Components 1. **NostrHandler** (`src/nostr_handler.py`) - Manages connections to multiple Nostr relays - Handles subscriptions and event publishing - Supports parallel relay operations - Built-in event deduplication 2. **BisqClient** (`src/bisq_client.py`) - Wraps bisq-cli commands - Async interface to Bisq daemon - Parses and formats marketplace data - Handles errors and timeouts 3. **MessageParser** (`src/message_parser.py`) - Parses user commands from Nostr mentions - Supports multiple command formats - Flexible pattern matching 4. **Formatter** (`src/formatter.py`) - Formats data for Nostr publication - Clean, readable output messages - Error message formatting 5. **BisqBot** (`src/bot.py`) - Main orchestration class - Coordinates all components - Handles event subscription and response ### Multi-Relay Architecture The bot connects to multiple relays simultaneously: ``` Bot ──┬──→ wss://relay.damus.io ├──→ wss://relay.nostr.band └──→ wss://nos.lol ``` All relays are connected in parallel and the bot: - Reads from all relays simultaneously (best relay wins) - Publishes to all relays at once (redundancy) - Deduplicates events from multiple relays - Handles relay failures gracefully ## Installation ### System Requirements - Python 3.9+ - Debian/Ubuntu Linux - Bisq daemon running locally (RPC port 4848) ### Quick Install ```bash cd /opt sudo git clone bisq-bot cd bisq-bot sudo bash setup.sh ``` The setup script will: 1. Install Python and dependencies 2. Create a `bisq` user 3. Set up a Python virtual environment 4. Install the bot 5. Create a systemd service ### Manual Installation 1. Create Python venv: ```bash python3 -m venv venv source venv/bin/activate ``` 2. Install dependencies: ```bash pip install -r requirements.txt ``` 3. Configure: ```bash cp config/.env.example .env # Edit .env and add your BOT_PRIVATE_KEY ``` 4. Generate bot's Nostr private key: ```bash openssl rand -hex 32 # Add this to .env as BOT_PRIVATE_KEY ``` ## Configuration Edit `.env` file: ```bash # Nostr Relay Configuration (comma-separated) NOSTR_RELAYS=wss://relay.damus.io,wss://relay.nostr.band,wss://nos.lol # Bot's Nostr private key (hex format) BOT_PRIVATE_KEY=your_hex_key_here # Bisq daemon settings BISQ_PORT=4848 BISQ_HOST=127.0.0.1 # Bot settings BOT_NAME=bisqbot REQUEST_TIMEOUT=10 ``` ### Generating a Private Key ```bash openssl rand -hex 32 ``` This creates a new Nostr identity for the bot. **Do not reuse or share this key.** ## Running ### Development ```bash source venv/bin/activate python -m src.bot ``` ### Production (systemd) ```bash # Install service sudo cp config/bisq-bot.service /etc/systemd/system/ sudo systemctl daemon-reload # Start bot sudo systemctl start bisq-bot sudo systemctl enable bisq-bot # Auto-start on boot # Monitor sudo systemctl status bisq-bot journalctl -u bisq-bot -f # Follow logs ``` ## Usage ### User Commands Users mention the bot in Nostr with commands: #### Get Offers ``` @bisqbot USD BUY ``` Shows the top 10 USD buy offers sorted by price. ``` @bisqbot EUR SELL ``` Shows the top 10 EUR sell offers sorted by price. #### Market Statistics ``` @bisqbot STATS ``` Publishes daily market statistics. #### Help ``` @bisqbot HELP ``` Shows help text. ### Supported Currencies Any currency code supported by Bisq: - Fiat: USD, EUR, GBP, JPY, CNY, CAD, AUD, etc. - Other: BRL, INR, SEK, NOK, DKK, HUF, CZK, RON, etc. ## Monitoring ### Check Service Status ```bash sudo systemctl status bisq-bot ``` ### View Recent Logs ```bash journalctl -u bisq-bot -n 50 ``` ### Follow Live Logs ```bash journalctl -u bisq-bot -f ``` ### Check Relay Connections The bot logs connection status on startup. Check logs for relay connectivity issues. ## Architecture Details ### Event Flow 1. **User publishes mention**: "Get me USD sell offers @bisqbot" 2. **Bot receives on relay**: Event arrives via subscribed relay 3. **Message parsing**: Bot extracts command from mention 4. **Bisq query**: Bot queries local Bisq daemon via bisq-cli 5. **Response formatting**: Results formatted for Nostr 6. **Publication**: Response published to all connected relays 7. **Deduplication**: Event IDs tracked to prevent duplicate processing ### Relay Handling - **Connection**: All relays in config are connected simultaneously - **Read**: Events received from any relay are processed - **Write**: Events published to all relays for redundancy - **Failure handling**: If a relay disconnects, the bot continues operating - **Reconnection**: Relays reconnect automatically with backoff ### Performance Characteristics - **Response time**: 1-5 seconds typically (depends on Bisq daemon) - **CPU usage**: Minimal (async, non-blocking) - **Memory usage**: ~50-100 MB base + relay subscriptions - **Network**: Multiplexed across relays (no bandwidth explosion) ## Development ### Project Structure ``` bot/ ├── src/ │ ├── bot.py # Main orchestration │ ├── config.py # Configuration loading │ ├── nostr_handler.py # Nostr relay management │ ├── bisq_client.py # Bisq daemon wrapper │ ├── message_parser.py # Command parsing │ ├── formatter.py # Output formatting │ └── __init__.py ├── config/ │ ├── .env.example # Configuration template │ └── bisq-bot.service # systemd service file ├── tests/ # Unit tests (Phase 2) ├── requirements.txt ├── setup.sh └── README.md ``` ### Running Tests (Phase 2) ```bash pip install pytest pytest-asyncio pytest tests/ ``` ### Code Style This project follows PEP 8. Use `black` and `flake8` for style checking: ```bash pip install black flake8 black src/ flake8 src/ ``` ## Extending the Bot ### Adding New Commands 1. Add command type to `CommandType` enum in `message_parser.py` 2. Add pattern matching in `MessageParser._match_pattern()` 3. Add handler in `BisqBot._process_command()` 4. Add formatter in `formatter.py` ### Connecting to a New Relay Just add the relay URL to `NOSTR_RELAYS` in `.env`. No code changes needed. ### Customizing Response Format Edit `Formatter` class methods in `src/formatter.py`. ## Troubleshooting ### Bot doesn't respond to mentions 1. **Check relay connectivity**: `journalctl -u bisq-bot -f` 2. **Verify bot pubkey**: Check logs for bot's public key 3. **Check mention format**: Must be `@bisqbot` or mention the bot's pubkey 4. **Verify Bisq daemon**: `bisq-cli --port=4848 getoffers --direction=BUY --currency-code=USD` ### Bisq daemon connection fails 1. **Check Bisq is running**: `ps aux | grep bisq` 2. **Check port**: `sudo netstat -tlnp | grep 4848` 3. **Verify configuration**: Check `BISQ_PORT` and `BISQ_HOST` in `.env` 4. **Test bisq-cli directly**: `bisq-cli --port=4848 getoffers --direction=BUY --currency-code=USD` ### High CPU or memory usage 1. **Check relay count**: Reduce number of relays if needed 2. **Monitor event deduplication**: Check logs for event duplicate counts 3. **Check Bisq responsiveness**: Bisq daemon may be under load ## Phase 2: Planned Features - [x] Phase 1: Core bot with multi-relay support ✅ - [ ] Phase 2: User interactions and advanced commands - DM-based conversations - Price alerts - Order placement - [ ] Phase 3: Scheduled tasks - Daily market statistics publication - Historical data collection - PostgreSQL persistence - [ ] Phase 4: Analytics and dashboards - Market trends - Volume analysis - Price history ## Contributing Contributions welcome! Please follow PEP 8 and include tests for new features. ## License This project is part of the Bisq project and follows its licensing terms. ## Support For issues, questions, or suggestions, please open an issue on the repository. ## See Also - [Bisq Project](https://bisq.network) - [Nostr Protocol](https://github.com/nostr-protocol/nostr) - [Nostr SDK for Python](https://github.com/rust-nostr/nostr-sdk-py)