bisq-bot/bot/README.md
shakespeare.diy baf3a22c44 Phase 1: Core Bisq bot with multi-relay support
Implements the foundation for a Nostr-based Bisq marketplace bot:

Core Components:
- NostrHandler: Multi-relay connection management with simultaneous subscribe/publish
- BisqClient: Async wrapper around bisq-cli for marketplace queries
- MessageParser: Flexible command parsing with multiple input formats
- Formatter: Response formatting for Nostr publication
- BisqBot: Main orchestration class coordinating all components

Features:
- Multiple relay support (parallel connections)
- Event deduplication across relays
- Async/await architecture for non-blocking operations
- Comprehensive error handling and recovery
- Flexible command syntax (e.g., "USD BUY", "stats", "help")

Configuration:
- Environment-based configuration with sensible defaults
- Support for N relays via comma-separated config
- Bisq daemon connection configuration

Documentation:
- README.md: Complete user guide with installation and usage
- QUICKSTART.md: 10-minute setup guide
- ARCHITECTURE.md: Detailed technical architecture and design
- RELAY_STRATEGY.md: Multi-relay configuration and optimization

Deployment:
- systemd service file for production deployment on Debian
- setup.sh automated installation script
- .env.example configuration template

Phase 1 Status:  COMPLETE
- Core bot skeleton
- Multi-relay support (no relay dependency needed)
- Nostr subscription and publishing
- Bisq query integration
- Basic command parsing and response
2025-11-01 07:53:03 +00:00

8.5 KiB

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

cd /opt
sudo git clone <this-repo> 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:
python3 -m venv venv
source venv/bin/activate
  1. Install dependencies:
pip install -r requirements.txt
  1. Configure:
cp config/.env.example .env
# Edit .env and add your BOT_PRIVATE_KEY
  1. Generate bot's Nostr private key:
openssl rand -hex 32
# Add this to .env as BOT_PRIVATE_KEY

Configuration

Edit .env file:

# 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

openssl rand -hex 32

This creates a new Nostr identity for the bot. Do not reuse or share this key.

Running

Development

source venv/bin/activate
python -m src.bot

Production (systemd)

# 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

sudo systemctl status bisq-bot

View Recent Logs

journalctl -u bisq-bot -n 50

Follow Live Logs

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)

pip install pytest pytest-asyncio
pytest tests/

Code Style

This project follows PEP 8. Use black and flake8 for style checking:

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

  • 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