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.sh/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 Distribution

sardis_ledger-1.0.0.tar.gz (73.9 kB view details)

Uploaded Source

Built Distribution

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

sardis_ledger-1.0.0-py3-none-any.whl (71.1 kB view details)

Uploaded Python 3

File details

Details for the file sardis_ledger-1.0.0.tar.gz.

File metadata

  • Download URL: sardis_ledger-1.0.0.tar.gz
  • Upload date:
  • Size: 73.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for sardis_ledger-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f4c0852c09c78d267203548faf5b72f1af0cfa4c8f2418418c0b1a89efcb3e18
MD5 bdd146a5507fa96a41060b3abad73679
BLAKE2b-256 ca7b86633d3e9493195e4eb58b2dcee5534db841c7cbf62e64b374e16b7900d1

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for sardis_ledger-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eb982243c5d873afde95520481fa8df19b0a49da8c262f05c9aa1ef54a30e540
MD5 619d86dcbf1fd04ce2c2389a1dc52f6b
BLAKE2b-256 47adbff8a5acb1e6f552f56f7d0b4c91d040c149e654cbeaf010b33ffed59130

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