Skip to main content

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

Project description

sardis-ledger

PyPI version Python 3.11+ License: 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

pip install sardis-ledger

Optional Dependencies

# 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

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

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

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

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

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)

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)

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.io/ledger.

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please see our Contributing Guide for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sardis_ledger-0.3.1-py3-none-any.whl (52.9 kB view details)

Uploaded Python 3

File details

Details for the file sardis_ledger-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: sardis_ledger-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 52.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for sardis_ledger-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c4f0247fce4d4f4d2811b5a88f813113b176906686af7ed3a254f5f66b65ada1
MD5 4058005b4118238df19f498a15e4a822
BLAKE2b-256 6dbc009cf7d30facd94b1318a773fa1765fae5698d3eaf1ad1d75d9745365279

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page