Metadata-Version: 2.4
Name: sardis-ledger
Version: 1.1.0
Summary: Production-grade append-only ledger with row-level locking, batch processing, and blockchain reconciliation
Project-URL: Homepage, https://sardis.sh
Project-URL: Documentation, https://sardis.sh/docs
Project-URL: Repository, https://github.com/EfeDurmaz16/sardis
Project-URL: Changelog, https://github.com/EfeDurmaz16/sardis/blob/main/CHANGELOG.md
Project-URL: Bug Tracker, https://github.com/EfeDurmaz16/sardis/issues
Author-email: Sardis Team <dev@sardis.sh>
Maintainer-email: Sardis Team <dev@sardis.sh>
License: MIT
License-File: LICENSE
Keywords: accounting,audit-trail,blockchain,fintech,immutable,ledger,merkle-tree,reconciliation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Office/Business :: Financial :: Accounting
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: sardis-core>=0.1.0
Requires-Dist: sqlalchemy>=2.0
Provides-Extra: all
Requires-Dist: asyncpg>=0.28.0; extra == 'all'
Requires-Dist: immudb-py>=1.5.0; extra == 'all'
Requires-Dist: mypy>=1.7; extra == 'all'
Requires-Dist: pytest-asyncio>=0.21; extra == 'all'
Requires-Dist: pytest-cov>=4.0; extra == 'all'
Requires-Dist: pytest>=7.0; extra == 'all'
Requires-Dist: ruff>=0.1; extra == 'all'
Requires-Dist: web3>=6.0.0; extra == 'all'
Provides-Extra: anchoring
Requires-Dist: web3>=6.0.0; extra == 'anchoring'
Provides-Extra: dev
Requires-Dist: mypy>=1.7; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1; extra == 'dev'
Provides-Extra: immudb
Requires-Dist: immudb-py>=1.5.0; extra == 'immudb'
Provides-Extra: postgres
Requires-Dist: asyncpg>=0.28.0; extra == 'postgres'
Description-Content-Type: text/markdown

# sardis-ledger

[![PyPI version](https://badge.fury.io/py/sardis-ledger.svg)](https://badge.fury.io/py/sardis-ledger)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Production-grade append-only ledger with row-level locking, batch processing, and blockchain reconciliation.

## Overview

`sardis-ledger` provides an immutable audit and settlement ledger for financial operations:

- **Append-Only Records**: Immutable ledger entries with Merkle tree receipts
- **Row-Level Locking**: Concurrent transaction support with deadlock prevention
- **Batch Processing**: Atomic multi-entry commits with rollback support
- **Blockchain Reconciliation**: Automated chain state reconciliation
- **Balance Snapshots**: Point-in-time balance queries
- **Hybrid Storage**: PostgreSQL + immudb for verified immutability

## Installation

```bash
pip install sardis-ledger
```

### Optional Dependencies

```bash
# PostgreSQL async support
pip install sardis-ledger[postgres]

# immudb for verified immutability
pip install sardis-ledger[immudb]

# Blockchain anchoring
pip install sardis-ledger[anchoring]

# All optional dependencies
pip install sardis-ledger[all]
```

## Quick Start

```python
from sardis_ledger import LedgerEngine, LedgerEntryType
from decimal import Decimal

# Initialize the ledger
engine = LedgerEngine(database_url="postgresql://...")

# Create a ledger entry
entry = await engine.create_entry(
    account_id="acc_123",
    amount=Decimal("100.50"),
    entry_type=LedgerEntryType.CREDIT,
    reference="payment_456",
)

print(f"Entry ID: {entry.entry_id}")
print(f"Balance: {entry.running_balance}")
print(f"Merkle Root: {entry.merkle_root}")
```

## Features

### Ledger Operations

```python
from sardis_ledger import LedgerEngine, LedgerEntryType
from decimal import Decimal

engine = LedgerEngine(database_url="postgresql://...")

# Credit an account
credit = await engine.create_entry(
    account_id="acc_123",
    amount=Decimal("500.00"),
    entry_type=LedgerEntryType.CREDIT,
    reference="deposit_789",
    metadata={"source": "bank_transfer"},
)

# Debit an account
debit = await engine.create_entry(
    account_id="acc_123",
    amount=Decimal("100.00"),
    entry_type=LedgerEntryType.DEBIT,
    reference="withdrawal_012",
)

# Get current balance
balance = await engine.get_balance("acc_123")
print(f"Current balance: {balance}")
```

### Batch Processing

```python
from sardis_ledger import LedgerEngine

engine = LedgerEngine(database_url="postgresql://...")

# Create a batch of entries (atomic commit)
batch = await engine.create_batch([
    {
        "account_id": "acc_sender",
        "amount": "500.00",
        "entry_type": "debit",
        "reference": "transfer_123",
    },
    {
        "account_id": "acc_receiver",
        "amount": "500.00",
        "entry_type": "credit",
        "reference": "transfer_123",
    },
])

print(f"Batch ID: {batch.batch_id}")
print(f"Entries: {len(batch.entries)}")

# Rollback if needed
await engine.rollback_batch(
    batch_id=batch.batch_id,
    reason="Customer requested refund",
)
```

### Row-Level Locking

```python
from sardis_ledger import LedgerEngine, LockManager

lock_manager = LockManager()
engine = LedgerEngine(lock_manager=lock_manager)

# Acquire lock for concurrent safety
async with engine.lock_account("acc_123"):
    balance = await engine.get_balance("acc_123")
    if balance >= amount:
        await engine.create_entry(
            account_id="acc_123",
            amount=amount,
            entry_type=LedgerEntryType.DEBIT,
        )
```

### Blockchain Reconciliation

```python
from sardis_ledger import ReconciliationEngine, ChainProvider

reconciler = ReconciliationEngine(
    ledger=engine,
    chain_provider=ChainProvider(chain="base"),
)

# Run reconciliation
report = await reconciler.reconcile(
    start_block=1000000,
    end_block=1001000,
)

print(f"Matched: {report.matched_count}")
print(f"Discrepancies: {len(report.discrepancies)}")

for disc in report.discrepancies:
    print(f"  {disc.type}: {disc.description}")
```

### Immutable Audit Trail (with immudb)

```python
from sardis_ledger import create_audit_trail, ImmutableConfig

# Create immutable audit trail
audit = create_audit_trail(
    config=ImmutableConfig(
        host="localhost",
        port=3322,
        database="sardis_audit",
    )
)

# Write an audit entry
receipt = await audit.write(
    entry_id=entry.entry_id,
    data=entry.to_dict(),
)

print(f"Verified at: {receipt.timestamp}")
print(f"Merkle proof: {receipt.merkle_proof}")

# Verify an entry
verification = await audit.verify(entry.entry_id)
assert verification.status == VerificationStatus.VERIFIED
```

### Hybrid Ledger (PostgreSQL + immudb)

```python
from sardis_ledger import create_hybrid_ledger, HybridConfig

# Create hybrid ledger for best of both worlds
ledger = create_hybrid_ledger(
    config=HybridConfig(
        postgres_url="postgresql://...",
        immudb_host="localhost",
        immudb_port=3322,
    )
)

# Entries are written to both stores
entry = await ledger.create_entry(
    account_id="acc_123",
    amount=Decimal("100.00"),
    entry_type=LedgerEntryType.CREDIT,
)

# Get hybrid receipt with both proofs
print(f"PostgreSQL ID: {entry.receipt.pg_id}")
print(f"immudb TX: {entry.receipt.immudb_tx}")
```

## Architecture

```
sardis-ledger/
├── models.py         # Data models and enums
├── records.py        # Core ledger store
├── engine.py         # Ledger engine with locking
├── reconciliation.py # Blockchain reconciliation
├── immutable.py      # immudb integration
└── hybrid.py         # Hybrid storage
```

## Requirements

- Python 3.11+
- sardis-core >= 0.1.0
- sqlalchemy >= 2.0

## Documentation

Full documentation is available at [docs.sardis.sh/ledger](https://docs.sardis.sh/ledger).

## License

MIT License - see [LICENSE](LICENSE) for details.

## Contributing

Contributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
