# Sophi

**Balance-based non-custodial swap language for Bitcoin.**

Sophi is a language with one primitive: the balance. When both sides are equal, a non-custodial atomic swap executes on Bitcoin. No escrow. No intermediary. No custodian.

## Install

```
pip install sophi
```

## Write a swap

```
swap {
  alice wants  0.5 BTC
  alice gives  50000 USDT

  bob wants    50000 USDT
  bob gives    0.5 BTC
}
```

Save as `trade.sph` and run:

```
sophi compile trade.sph
```

## Blind swap (private values)

```
swap {
  alice wants  blind(a3f8c2d1e4b7a9f0c2d1e4b7a9f0c2d1e4b7a9f0c2d1e4b7a9f0c2d1e4b7a9f0)
  alice gives  blind(b1e2d3c4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2)

  bob wants    blind(b1e2d3c4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2)
  bob gives    blind(a3f8c2d1e4b7a9f0c2d1e4b7a9f0c2d1e4b7a9f0c2d1e4b7a9f0c2d1e4b7a9f0)
}
```

Nobody sees the amounts until settlement. This is the foundation of OTC dark pool privacy.

## How it works

- `wants` — what a party wants to receive
- `gives` — what a party is offering
- `blind(hash)` — hides the value using SHA-256 commitment
- `partial` — accepts partial fill
- `expires block(N)` — swap expires at Bitcoin block N

The compiler checks that all balances are in equilibrium before generating anything. If `alice gives` does not equal `bob wants`, you get a clear error — not a runtime failure on a live network.

## Multi-party

```
swap {
  alice wants  blind(H1)
  alice gives  blind(H2)

  bob wants    blind(H2)
  bob gives    blind(H3)

  carol wants  blind(H3)
  carol gives  blind(H1)
}
```

Up to 8 parties. All legs settle atomically.

## Non-custodial by construction

Sophi has no syntax for depositing funds into a contract. The only thing you can express is a condition for transfer. Custodial code is not forbidden — it is unwritable.

## License

Business Source License 1.1 — converts to Apache 2.0 after 4 years.
