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_registry↔asset_states(1:1 viaasset_id)
One-to-Many
asset_registry→asset_transactions(1:N viaasset_id)asset_registry→asset_events(1:N viaasset_id)asset_registry→gas_ledger(1:N viaasset_id, optional)asset_registry→xrpl_sync_log(1:N viaasset_id, optional)asset_registry→asset_registry(self-referential for packs/bundles viaparent_container_id)
Foreign Keys
asset_states.asset_id→asset_registry.id(CASCADE)asset_transactions.asset_id→asset_registry.id(CASCADE)asset_events.asset_id→asset_registry.id(CASCADE)gas_ledger.asset_id→asset_registry.id(SET NULL)xrpl_sync_log.asset_id→asset_registry.id(SET NULL)asset_registry.issuer_user_id→auth.users.idasset_states.owner_user_id→auth.users.idasset_states.parent_container_id→asset_registry.idasset_transactions.actor_user_id→auth.users.idasset_transactions.from_user_id→auth.users.idasset_transactions.to_user_id→auth.users.idasset_events.user_id→auth.users.idgas_ledger.user_id→auth.users.idgas_ledger.related_transaction_id→asset_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:
- Query XRPL Sync Log: Get all transactions for an asset
- Replay Transactions: Process each transaction in order
- Update Asset State: Rebuild
asset_statesfrom transaction history - 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_statesprovides fast current-state queries without scanning transaction history- Updated on every transaction
- Allows instant ownership/custody lookups
Partitioning (Future)
- Consider partitioning
asset_transactionsby date for large-scale deployments - Consider partitioning
xrpl_sync_logby ledger_index
Future Enhancements
- Asset Bundles: Support for complex bundle structures
- Fraction Trading: Track fraction ownership and trading
- Marketplace Integration: Direct integration with marketplace listings
- Analytics: Pre-computed analytics tables for dashboards
- Event Sourcing: Full event sourcing pattern for complete auditability
