Deterministic, offline-verifiable proof-of-reserves and a tamper-evident audit chain for TradFi (no on-chain oracle).
Project description
openreserve
A small, self-contained verification core for deterministic, offline-verifiable proof-of-reserves and a tamper-evident audit chain. It is early and has no production adoption yet — see Status.
What it does
Given a ledger state (an append-only double-entry ledger) and an explicit point in time, it produces and verifies:
- Proof of Reserves — a Merkle tree over user-account balances plus reserve-account
totals, with a solvency check (
reserves >= liabilities). Each user can verify their own balance is included via a Merkle proof, without the operator revealing other users' balances. - Proof of Solvency — per-currency proof-of-reserves aggregated with the audit-chain commitment hash.
- Audit chain — a hash-linked event log (
prev_hash→event_hash) withverify_chain()for end-to-end integrity / tamper detection. - Reserve / deposit calculation — point-in-time required-reserve computation (settled user balances + in-flight obligations, negative balances excluded).
All artifacts are plain data (to_public_summary() returns JSON-serializable dicts).
A produced proof can be published at a static URL and independently re-verified
offline by a third party using this library — e.g. fetch the JSON with curl and
re-run the Merkle / chain verification locally. This core does not ship an HTTP
serving layer; exposing an endpoint is left to the integrator.
Determinism is the core property
Proof generation takes the as-of / event time as an explicit input and never reads
the wall clock (datetime.now()). Identical inputs + identical explicit time produce a
byte-identical artifact hash. This is what makes a published proof reproducible by anyone.
"Verify me"
Don't take the above on trust — the bundled guard checks it:
python -m pytest tests/test_determinism_guard.py -v
It asserts (a) the same ledger state + same snapshot_at reproduces the same Merkle
root and audit hash, and (b) with datetime.now patched to raise, generation with an
explicit time still succeeds (the wall clock is never touched).
Run the full suite:
python -m pytest -q
Usage
from datetime import datetime, timezone
from openreserve import (
Currency,
Ledger,
Money,
OwnerType,
ProofOfReservesGenerator,
SQLiteLedgerStorage,
TransactionBuilder,
)
# A fixed, explicit point in time — proofs never read the wall clock.
T = datetime(2026, 1, 1, tzinfo=timezone.utc)
ledger = Ledger(SQLiteLedgerStorage(":memory:"))
platform = ledger.open_account(OwnerType.PLATFORM, Currency.JPY, "platform")
reserve = ledger.open_account(OwnerType.RESERVE, Currency.JPY, "reserve")
alice = ledger.open_account(OwnerType.USER, Currency.JPY, "alice")
def fund(src, dst, units):
b = TransactionBuilder("FUND", "ops", initiated_at=T)
b.transfer(src.account_id, dst.account_id, Money.from_units(units, Currency.JPY))
ledger.post(b.build())
ledger.settle(b.transaction_id, settled_at=T)
fund(platform, reserve, 1_000_000) # reserve assets
fund(platform, alice, 300_000) # a user balance (liability)
gen = ProofOfReservesGenerator(ledger)
proof, _tree = gen.generate(currency=Currency.JPY, snapshot_at=T)
print("solvent: ", proof.is_solvent) # True
print("liabilities: ", proof.user_liabilities_total_cents) # 300000
print("reserves: ", proof.reserve_assets_total_cents) # 1000000
print("merkle root: ", proof.user_liabilities_root[:16] + "...")
# Determinism: same ledger state + same snapshot_at -> identical Merkle root.
proof2, _ = gen.generate(currency=Currency.JPY, snapshot_at=T)
print("reproducible:", proof.user_liabilities_root == proof2.user_liabilities_root) # True
Positioning
This targets non-crypto / TradFi use: a payment, wallet, or custody operator proving that safeguarded customer funds are backed by reserves, as a point-in-time, auditable, offline-verifiable artifact — without requiring an on-chain oracle. Reserve proof is the primary use case.
It is not an on-chain proof-of-reserves system and is not positioned to compete with on-chain PoR oracles (e.g. Chainlink). There is no blockchain dependency; the "chain" here is a local hash-linked audit log, not a distributed ledger.
What it does NOT do
- No HTTP server / public endpoint (artifacts are data; serving is the integrator's job).
- No payment, payout, FX-conversion, KYC, or business-application orchestration logic.
- No external network or cloud dependency at runtime (SQLite + standard library only).
- No on-chain anchoring or third-party attestation (could be layered on top).
Status
- Early / unproven. No production deployments. APIs may change.
- Identifiers (
transaction_id,account_id) are currently UUID-based, so they vary across independent runs; determinism guarantees here cover the time axis (fixed ledger state + fixed time → identical artifacts), not identifier stability.
Install / requirements
- Python 3.11+
- Runtime dependencies: none (standard library only —
sqlite3,hashlib, …). - Test dependency:
pytest(via thetestextra).
pip install -e . # editable install
pip install -e ".[test]" # editable install + pytest
python -m pytest -q # run the suite
Layout
openreserve/
__init__.py public API re-exports (+ __version__)
core/ append-only double-entry ledger + types + SQLite storage
transparency/ merkle tree, hash-chain audit log, proof generators
regulatory/ point-in-time reserve / deposit calculation
providers/ abstract provider interface (ProviderCategory only; no implementations)
tests/ unit tests + determinism guard
Project
- Architecture — modules, dependency graph, trust model, extension points
- Verifying a proof — re-verify a published proof offline ("verify me")
- Examples — runnable scripts (proof-of-reserves, offline verify, tamper detection, reproducibility)
- Contributing · Code of Conduct · Security
- Roadmap — directions (exploratory, not promises) · Changelog
License
Apache License 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openreserve-0.1.1.tar.gz.
File metadata
- Download URL: openreserve-0.1.1.tar.gz
- Upload date:
- Size: 50.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a96228ff1d483feabe61fd673f3a24e8d9b8a9bd8730aa86347f15a94efc030c
|
|
| MD5 |
4b5523719124fbd50b6c39210fc9884e
|
|
| BLAKE2b-256 |
93bdb8fd9c0de8b8f6202480e0026a2100bd427fbf7d6833cd7f38b9a8460f86
|
File details
Details for the file openreserve-0.1.1-py3-none-any.whl.
File metadata
- Download URL: openreserve-0.1.1-py3-none-any.whl
- Upload date:
- Size: 40.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f80ef45ba3a30abc364a2d44434a72ed08128a11ab7bbe8318198e0eef94d687
|
|
| MD5 |
930adce1eb40bdcbae7994be2f111aa2
|
|
| BLAKE2b-256 |
e1e73756225b917a0ac41c6638b36266f55764f94584a404c9629a9385cebb31
|