# Open Swarm Protocol (Satshoal)

**Version 0.2.0** · **BT bytes + Lightning money + Nostr gossip.** MIT licensed.

Open protocol for paying seeders (lud16 / BOLT11) while bytes move over BitTorrent / WebTorrent and discovery moves over Nostr.

> **Legal:** Clients **MAY** seed any content users choose. Hosted indexes **SHOULD** filter (see [`SPEC.md`](./SPEC.md)). The reference web demo keeps an allowlisted catalog and does **not** ingest arbitrary magnets into its server API. For arbitrary magnets, run a **local** thick client — we don’t host illegal indexes.

## Install (self-contained)

```bash
cd protocol   # or clone root and cd protocol
python3 -m pip install -e .
python3 -c "import open_swarm_protocol as p; print(p.__version__, sorted(p.ALLOWLIST)[:3])"
```

No hard runtime dependencies. Optional: use alongside the Flask demo or thick CLI.

## Architecture

```
Discovery (Nostr 39000/39001)  →  Payment (LN to seeder lud16)  →  Bytes (BT / WebTorrent / webseed)
```

| Concern | Mechanism |
|---------|-----------|
| Who has the file? | Nostr `content_listing` + `seeder_ad` |
| Who gets paid? | Invoice to `ln_receive` (Lightning address) |
| How do bytes move? | BitTorrent infohash / magnet / WebTorrent; optional HTTP webseed |
| Keep seeders online? | Retainer bounty + piece challenges |

## Event kinds

| Kind | Name |
|------|------|
| 39000 | content_listing |
| 39001 | seeder_ad (includes `ln_receive`) |
| 39002 | retainer_bounty |
| 39003 | retainer_fund |
| 39004 | challenge_result |
| 39005 | attestation (stub) |

Public Nostr announce is **optional** and not required by this package.

## Piece / HTLC invoice format

```
infohash|piece_index|piece_hash|nonce
```

Whole file (demo):

```
infohash|ALL|remaining_count|file_hash|nonce
```

Alias:

```
infohash|FILE|file_hash|nonce
```

Production SHOULD prefer hold invoices so settlement aligns with verifiable delivery.

## License gate (hosted indexes)

```python
from open_swarm_protocol import require_allowed, build_seeder_ad

require_allowed("MIT")  # ok
ad = build_seeder_ad(
    infohash="abc…",
    ln_receive="you@lexe.app",
    sats_per_piece=21,
    license_spdx="MIT",
)
```

## Repo layout

```
SPEC.md                 Normative draft
README.md               This file
VERSION                 0.2.0
pyproject.toml          Packaging
LICENSE                 MIT
open_swarm_protocol/    Importable helpers
```

## Reference implementations (box paths)

| Path | Role |
|------|------|
| `..` | Flask web demo + allowlisted fixtures + WebTorrent seed-on-click |
| `../thick-client` | Phase 4 CLI thick seeder (allowlisted fixtures by default) |

## Publish status

GitHub create requires Cursor → GitHub auth. Local tree is ready to push once SCM is connected:

```bash
cd protocol   # or clone root and cd protocol
git remote add origin git@github.com:<USER>/open-swarm-protocol.git
git push -u origin main
```
