Metadata-Version: 2.4
Name: orphograph
Version: 0.1.0
Summary: Anchor folders to Bitcoin via the Orphograph hosted service. File contents stay on the local machine.
Author: the Orphograph contributors
License: MIT License
        
        Copyright (c) 2026 the Orphograph contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://orphograph.com
Project-URL: Documentation, https://orphograph.com/method/architecture.html
Keywords: bitcoin,opentimestamps,merkle,notarization,provenance
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: System :: Archiving
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# orphograph

A Python SDK for anchoring a local folder to the Bitcoin chain through the
[Orphograph](https://orphograph.com) hosted service.

- License: MIT
- Python: 3.9 or newer
- Runtime dependencies: Python standard library only

## Privacy contract

The library does not transmit file contents. For each file the SDK reads
the bytes locally, streams them through SHA-256 in one megabyte chunks,
and commits the digest into an RFC 6962 Merkle leaf bound to the file's
POSIX relative path. Only the resulting manifest (paths, per-file digests,
leaf hashes, and the 32-byte root) is sent across the network. The
verification path is symmetric: the root is recomputed locally from the
folder on disk and compared to the root recorded in the receipt.

The Merkle module is a verbatim copy of the server's reference
implementation, carrying the source SHA-256 in its header so divergence
from the canonical algorithm is immediately visible.

## Install

```
pip install orphograph
```

## Anchor a folder

```python
from orphograph import anchor_folder

result = anchor_folder("/path/to/folder")
# {
#   "receipt_id": "...",
#   "root_hex": "...",
#   "leaf_count": 42,
#   "calendars_ok": 5,
#   "calendars_total": 5,
# }
```

Optional arguments:

| Argument       | Purpose                                                  |
| -------------- | -------------------------------------------------------- |
| `server_url`   | Base URL of the service (default `https://orphograph.com`). |
| `api_key`      | Sent as `X-Orpho-Api-Key` when present.                  |
| `client_label` | Short free-form label persisted with the receipt.        |
| `exclude`      | Sequence of `fnmatch` patterns. `None` selects the default deny list (OS detritus, editor backups, build caches). Passing `[]` disables exclusion. |

## Verify a folder

```python
from orphograph import verify_folder

ok = verify_folder("/path/to/folder", receipt_id="...")
```

The folder is walked locally, the Merkle root is recomputed, and the SDK
returns `True` only if the recomputed root equals the root recorded in
the receipt's manifest.

## Inclusion proofs

A folder receipt can be queried for a proof that a single file belonged
to the anchored tree. The proof is verified locally; no further network
call is required to confirm it.

```python
from orphograph import inclusion_proof, verify_inclusion

proof = inclusion_proof(receipt_id="...", path="sub/photo.jpg")
ok = verify_inclusion(
    file_path="/path/to/sub/photo.jpg",
    rel_path="sub/photo.jpg",
    proof=proof["proof"],
    root_hex=proof["root_hex"],
)
```

## Command line

The package installs an `orphograph` console script and is also runnable
as a module.

```
python -m orphograph anchor /path/to/folder
python -m orphograph verify /path/to/folder <receipt_id>
python -m orphograph inclusion-proof <receipt_id> <posix/rel/path>
```

Each subcommand writes a single line of JSON to standard output. The
`verify` subcommand exits with status `0` on a match and `1` on a
mismatch.

Environment variables:

| Variable           | Purpose                                       |
| ------------------ | --------------------------------------------- |
| `ORPHO_SERVER_URL` | Default base URL.                             |
| `ORPHO_API_KEY`    | Default API key (sent as `X-Orpho-Api-Key`).  |

## Algorithm

The Merkle construction is RFC 6962 with a domain-separated leaf
(`0x00 || rel_path_utf8 || 0x00 || file_sha256`) and a domain-separated
internal node (`0x01 || left || right`). Odd-level remainders are
promoted, never duplicated, to avoid the second-preimage ambiguity of
the duplicate-last construction. The algorithm tag
`orphograph-merkle-v1-rfc6962` is embedded in every manifest.

## License

MIT. See `LICENSE`.
