Back to Documentation

LayerLedger Architecture

Overview

LayerLedger is a full hybrid ledger system that tracks both on-chain (XRPL) and off-chain (managed custody) events for the entire LayerVerse ecosystem. It serves as a Layer 2 sequencer log that provides provable provenance, instant lookups, and complete asset timelines.


Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────┐
│                         LAYERLEDGER SYSTEM                              │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│                    layer_engine.asset_registry                          │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │ Global Asset List (Source of Truth)                              │  │
│  │ • id, asset_type, app_id                                         │  │
│  │ • nfc_uuid (TapMint) OR mpt_issuance_id (XRPL)                  │  │
│  │ • title, thumbnail_url, issuer_user_id                           │  │
│  └──────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    │ 1:1
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                    layer_engine.asset_states                            │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │ Current State Snapshot (Fast Queries)                            │  │
│  │ • owner_user_id                                                  │  │
│  │ • custody_type (onchain | managed | hybrid)                      │  │
│  │ • fraction_count, container_type                                 │  │
│  │ • parent_container_id (for packs/bundles)                        │  │
│  │ • onchain_status                                                 │  │
│  └──────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                    ┌───────────────┼───────────────┐
                    │               │               │
                    ▼               ▼               ▼
┌─────────────────────────┐ ┌─────────────────────────┐ ┌─────────────────────────┐
│ asset_transactions      │ │ asset_events            │ │ gas_ledger              │
│ (Provable Changes)      │ │ (Social/View Events)    │ │ (Managed Custody Gas)   │
│                         │ │                         │ │                         │
│ • MINTED                │ │ • SCANNED               │ │ • gas_required          │
│ • TRANSFERRED           │ │ • STORY_ADDED           │ │ • gas_paid_by_user      │
│ • FRACTIONED            │ │ • VIEWED                │ │ • gas_paid_by_treasury  │
│ • MERGED                │ │ • PACK_TAPPED           │ │ • treasury_tx_hash      │
│ • PACK_CREATED          │ │ • SOCIAL_ACTION         │ │                         │
│ • PACK_OPENED           │ │ • REACTION_ADDED        │ │                         │
│ • BURNED                │ │ • COMMENT_ADDED         │ │                         │
│ • LISTED                │ │ • SHARED                │ │                         │
│ • SOLD                  │ │                         │ │                         │
│ • INTERNAL_GAS_CHARGE   │ │                         │ │                         │
│ • INTERNAL_GAS_COVERAGE │ │                         │ │                         │
│ • ONCHAIN_SEND          │ │                         │ │                         │
│ • ONCHAIN_RECEIVE       │ │                         │ │                         │
│ • ONCHAIN_BURN          │ │                         │ │                         │
│ • METADATA_UPDATED      │ │                         │ │                         │
└─────────────────────────┘ └─────────────────────────┘ └─────────────────────────┘
         │
         │ References
         ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                    layer_engine.xrpl_sync_log                           │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │ XRPL Transaction Sync (For Replay)                               │  │
│  │ • ledger_index, tx_hash                                          │  │
│  │ • tx_type, asset_id                                              │  │
│  │ • data (full transaction JSONB)                                  │  │
│  │ • synced_at                                                      │  │
│  └──────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────┘
         │
         │ Periodic Commitments
         ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                    layer_engine.checkpoints                             │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │ Hash Commitments (State Anchoring)                               │  │
│  │ • state_root (Merkle root of asset_states)                       │  │
│  │ • tx_root (Merkle root of asset_transactions)                    │  │
│  │ • xrpl_tx_hash (after anchoring to XRPL)                         │  │
│  │ • created_at, notes                                              │  │
│  └──────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│                         EXTERNAL SYSTEMS                                │
└─────────────────────────────────────────────────────────────────────────┘

┌──────────────────────┐         ┌──────────────────────┐
│   XRPL Blockchain    │◄────────┤  XRPL Sync Service   │
│                      │         │  (Watches XRPL)      │
│ • MPT Issuances      │         │                      │
│ • Payments           │         │  • Monitors ledger   │
│ • Escrows            │         │  • Syncs to log      │
└──────────────────────┘         └──────────────────────┘
         ▲
         │
         │ On-chain events
         │
┌──────────────────────┐
│  LayerVerse Apps     │
│                      │
│ • Mintlings          │─────────┐
│ • CardLayer          │         │
│ • LegacyLayer        │         │
└──────────────────────┘         │
                                 │
                                 │ Off-chain events
                                 │
                    ┌────────────┴────────────┐
                    │                         │
                    ▼                         ▼
         ┌──────────────────┐    ┌──────────────────┐
         │ Managed Custody  │    │  User Actions    │
         │                  │    │                  │
         │ • Off-chain DB   │    │ • Views          │
         │ • Gas accounting │    │ • Reactions      │
         │ • Treasury cover │    │ • Stories        │
         └──────────────────┘    └──────────────────┘

Data Flow

1. Asset Creation (Mint)

User Action → App (Mintlings/CardLayer/etc.)
    ↓
Create asset_registry entry
    ↓
Create asset_states entry (custody_type: 'managed' or 'onchain')
    ↓
Create asset_transactions entry (tx_type: 'MINTED')
    ↓
If on-chain: Create xrpl_sync_log entry
    ↓
If managed custody: Create gas_ledger entry

2. Asset Transfer

User Action → Transfer Request
    ↓
Update asset_states (owner_user_id, custody_type)
    ↓
Create asset_transactions entry (tx_type: 'TRANSFERRED')
    ↓
If on-chain: Create xrpl_sync_log entry + asset_transactions (ONCHAIN_SEND/RECEIVE)
    ↓
If managed custody: Create gas_ledger entry

3. Social Event (View, Reaction, Story)

User Action → Social Interaction
    ↓
Create asset_events entry (event_type: 'VIEWED', 'REACTION_ADDED', 'STORY_ADDED')
    ↓
(No state change, just event logging)

4. XRPL Sync (Background Process)

XRPL Monitor → New Transaction Detected
    ↓
Create xrpl_sync_log entry
    ↓
If transaction affects asset: Update asset_states + Create asset_transactions
    ↓
Reconcile on-chain state with internal state

Key Relationships

One-to-One

  • asset_registryasset_states (1:1 via asset_id)

One-to-Many

  • asset_registryasset_transactions (1:N via asset_id)
  • asset_registryasset_events (1:N via asset_id)
  • asset_registrygas_ledger (1:N via asset_id, optional)
  • asset_registryxrpl_sync_log (1:N via asset_id, optional)
  • asset_registryasset_registry (self-referential for packs/bundles via parent_container_id)

Foreign Keys

  • asset_states.asset_idasset_registry.id (CASCADE)
  • asset_transactions.asset_idasset_registry.id (CASCADE)
  • asset_events.asset_idasset_registry.id (CASCADE)
  • gas_ledger.asset_idasset_registry.id (SET NULL)
  • xrpl_sync_log.asset_idasset_registry.id (SET NULL)
  • asset_registry.issuer_user_idauth.users.id
  • asset_states.owner_user_idauth.users.id
  • asset_states.parent_container_idasset_registry.id
  • asset_transactions.actor_user_idauth.users.id
  • asset_transactions.from_user_idauth.users.id
  • asset_transactions.to_user_idauth.users.id
  • asset_events.user_idauth.users.id
  • gas_ledger.user_idauth.users.id
  • gas_ledger.related_transaction_idasset_transactions.id

Query Patterns

Provenance Query

-- Get full provenance for an asset
SELECT 
    ar.*,
    ast.*,
    at.*,
    ae.*
FROM asset_registry ar
LEFT JOIN asset_states ast ON ar.id = ast.asset_id
LEFT JOIN asset_transactions at ON ar.id = at.asset_id
LEFT JOIN asset_events ae ON ar.id = ae.asset_id
WHERE ar.id = $1
ORDER BY at.created_at ASC, ae.created_at ASC;

User History Query

-- Get all assets owned by a user
SELECT 
    ar.*,
    ast.*
FROM asset_states ast
JOIN asset_registry ar ON ast.asset_id = ar.id
WHERE ast.owner_user_id = $1
ORDER BY ast.last_updated_at DESC;

Gas Report Query

-- Get gas report for a user
SELECT 
    user_id,
    SUM(gas_required) as total_gas_required,
    SUM(gas_paid_by_user) as total_gas_paid_by_user,
    SUM(gas_paid_by_treasury) as total_gas_paid_by_treasury
FROM gas_ledger
WHERE user_id = $1
GROUP BY user_id;

State Reconstruction

The system supports state reconstruction from XRPL transactions:

  1. Query XRPL Sync Log: Get all transactions for an asset
  2. Replay Transactions: Process each transaction in order
  3. Update Asset State: Rebuild asset_states from transaction history
  4. Verify Consistency: Compare reconstructed state with current state

This allows:

  • Audit trails
  • State recovery
  • Cross-validation with XRPL
  • Historical state queries

Security & Permissions

RLS Policies

  • Public Read: Most tables allow public SELECT (for transparency)
  • Authenticated Write: Users can insert their own events
  • Service Role: Full access for system operations

Data Integrity

  • Foreign key constraints ensure referential integrity
  • Check constraints validate data types and values
  • Unique constraints prevent duplicates (NFC UUID, MPT Issuance ID)

Performance Considerations

Indexes

  • All foreign keys are indexed
  • Timestamp columns are indexed for time-based queries
  • Composite indexes for common query patterns (asset_id + created_at)

State Snapshots

  • asset_states provides fast current-state queries without scanning transaction history
  • Updated on every transaction
  • Allows instant ownership/custody lookups

Partitioning (Future)

  • Consider partitioning asset_transactions by date for large-scale deployments
  • Consider partitioning xrpl_sync_log by ledger_index

Future Enhancements

  1. Asset Bundles: Support for complex bundle structures
  2. Fraction Trading: Track fraction ownership and trading
  3. Marketplace Integration: Direct integration with marketplace listings
  4. Analytics: Pre-computed analytics tables for dashboards
  5. Event Sourcing: Full event sourcing pattern for complete auditability
SolidLayer Logo
LIQUIDITYLAYER

The modular core of CardLayer, LegacyLayer, and beyond — engineered with tRPC, monorepo architecture, and a stack that devs actually enjoy using.

Legal

© 2025 Layer.Company • Part of the LayerVerse

Built with ❤️ for the future