# Sophi

**A simple language for Bitcoin non-custodial smart contracts.**

Sophi has no runtime, no blockchain execution, and no custody of funds.
You describe what a fair exchange looks like — and Sophi proves it is mathematically valid.

## Install
```
pip install sophi
```

## Write a swap

Describe who has what before, and who has what after:
```
swap {
  before:
    alice = 0.5 BTC
    bob = 50000 USDT

  after:
    alice = 50000 USDT
    bob = 0.5 BTC
}
```

Run:
```
sophi compile trade.sph
```

Sophi verifies: BTC before == BTC after, USDT before == USDT after.
If the math holds, it produces a valid proof. If not, clear error.

## Transfer syntax

Same swap, different style:
```
swap {
  transfer 0.5 BTC from alice to bob
  transfer 50000 USDT from bob to alice
}
```

## Three or more participants
```
swap {
  transfer 0.5 BTC from alice to carol
  transfer 50000 USDT from bob to alice
  transfer 1 ETH from carol to bob
}
```

Any number of participants. All verified atomically.

## What the proof looks like
```json
{
  "swap_id": "f970dc4b...",
  "status": "valid",
  "conservation": {
    "BTC":  { "before": "0.5",   "after": "0.5"   },
    "USDT": { "before": "50000", "after": "50000"  }
  },
  "delta": {
    "alice": { "BTC": "-0.5",  "USDT": "+50000" },
    "bob":   { "BTC": "+0.5",  "USDT": "-50000" }
  },
  "htlc": {
    "secret_hash": "a3f8c2...",
    "timeout_blocks": 144,
    "legs": [
      { "from": "alice", "to": "bob",   "asset": "BTC",  "amount": "0.5"   },
      { "from": "bob",   "to": "alice", "asset": "USDT", "amount": "50000" }
    ]
  }
}
```

## Signatures are external

The `.sph` file never contains signatures or private keys.
After compiling, each party signs the `swap_id` using their own Bitcoin wallet:
```json
{
  "swap_id": "f970dc4b...",
  "signatures": {
    "alice": { "address": "bc1qalice...", "signature": "H7f8c2..." },
    "bob":   { "address": "bc1qbob...",   "signature": "K9d3e1..." }
  }
}
```

Then verify:
```python
from sophi import compile_source, verify_proof

compiled = compile_source(open("trade.sph").read())
result = verify_proof(compiled, proof_json)
# result["status"] == "signatures_valid"
```

## Rules that never change

- 1 BTC is never equal to 1 USDT — each asset verified separately
- No value is ever created or destroyed
- Funds never leave the participants control
- No on-chain execution — Sophi only verifies, never executes

## License

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