Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands - CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround - CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check - NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere - MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates - LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference Co-authored-by: Cursor <cursoragent@cursor.com>
209 lines
8.7 KiB
Markdown
209 lines
8.7 KiB
Markdown
# Normalized Event Schema v1
|
|
|
|
**Last Updated:** 2026-01-31
|
|
**Document Version:** 1.0
|
|
**Status:** Active Documentation
|
|
|
|
---
|
|
|
|
**Purpose:** Canonical schema for EII (Event Ingestion + Indexing), SAL (State & Accounting Ledger), and Mirroring Service. All chains (138, 651940, public mainnets) use this schema for blocks, transactions, receipts, logs, decoded_events, and execution_steps.
|
|
|
|
**Version:** 1.0
|
|
**Status:** Active
|
|
|
|
---
|
|
|
|
## 1. Design principles
|
|
|
|
- Append-only event store; no in-place updates.
|
|
- Every entity has `chain_id`, `created_at` (ingestion time).
|
|
- Hashes and addresses are lowercase hex with `0x` prefix.
|
|
- Optional fields may be null; required fields are non-null.
|
|
|
|
---
|
|
|
|
## 2. Blocks
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| chain_id | integer | yes | EVM chain ID (138, 651940, 1, etc.) |
|
|
| number | bigint | yes | Block number |
|
|
| hash | string(66) | yes | Block hash (0x + 64 hex) |
|
|
| parent_hash | string(66) | yes | Parent block hash |
|
|
| state_root | string(66) | no | State root |
|
|
| receipts_root | string(66) | no | Receipts root (for commitment leaves) |
|
|
| transactions_root | string(66) | no | Transactions root |
|
|
| miner | string(42) | no | Miner/validator address |
|
|
| difficulty | string | no | Block difficulty (numeric string) |
|
|
| total_difficulty | string | no | Total difficulty |
|
|
| size | bigint | no | Block size in bytes |
|
|
| gas_limit | bigint | yes | Gas limit |
|
|
| gas_used | bigint | yes | Gas used |
|
|
| timestamp | bigint | yes | Unix timestamp (seconds) |
|
|
| base_fee_per_gas | bigint | no | EIP-1559 base fee |
|
|
| transaction_count | integer | no | Number of transactions |
|
|
| extra_data | string | no | Extra data (hex) |
|
|
| created_at | string (ISO8601) | yes | Ingestion timestamp |
|
|
|
|
**Unique:** `(chain_id, number)`
|
|
**Indexes:** `(chain_id, number)`, `(chain_id, hash)`, `(chain_id, timestamp)`
|
|
|
|
---
|
|
|
|
## 3. Transactions
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| chain_id | integer | yes | EVM chain ID |
|
|
| hash | string(66) | yes | Transaction hash |
|
|
| block_number | bigint | yes | Block number |
|
|
| block_hash | string(66) | yes | Block hash |
|
|
| transaction_index | integer | yes | Index within block |
|
|
| from_address | string(42) | yes | Sender |
|
|
| to_address | string(42) | no | Recipient (null for contract creation) |
|
|
| value | string | yes | Value in wei (decimal string) |
|
|
| gas_price | bigint | no | Legacy gas price |
|
|
| max_fee_per_gas | bigint | no | EIP-1559 max fee |
|
|
| max_priority_fee_per_gas | bigint | no | EIP-1559 priority fee |
|
|
| gas_limit | bigint | yes | Gas limit |
|
|
| gas_used | bigint | no | Gas used (from receipt) |
|
|
| nonce | bigint | yes | Sender nonce |
|
|
| input_data | string | no | Calldata (hex) |
|
|
| status | integer | no | 0 = failed, 1 = success |
|
|
| contract_address | string(42) | no | Created contract (if creation) |
|
|
| cumulative_gas_used | bigint | no | From receipt |
|
|
| effective_gas_price | bigint | no | Actual gas price paid |
|
|
| created_at | string (ISO8601) | yes | Ingestion timestamp |
|
|
|
|
**Unique:** `(chain_id, hash)`
|
|
**Indexes:** `(chain_id, hash)`, `(chain_id, block_number, transaction_index)`, `(chain_id, from_address)`, `(chain_id, to_address)`
|
|
|
|
---
|
|
|
|
## 4. Receipts
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| chain_id | integer | yes | EVM chain ID |
|
|
| transaction_hash | string(66) | yes | Transaction hash |
|
|
| transaction_index | integer | yes | Index in block |
|
|
| block_number | bigint | yes | Block number |
|
|
| block_hash | string(66) | yes | Block hash |
|
|
| from_address | string(42) | yes | Sender |
|
|
| to_address | string(42) | no | Recipient |
|
|
| gas_used | bigint | no | Gas used |
|
|
| cumulative_gas_used | bigint | no | Cumulative gas |
|
|
| contract_address | string(42) | no | Created contract |
|
|
| logs_bloom | string | no | Logs bloom (hex) |
|
|
| status | integer | no | 0 = failed, 1 = success |
|
|
| root | string(66) | no | Pre-Byzantium state root |
|
|
| created_at | string (ISO8601) | yes | Ingestion timestamp |
|
|
|
|
**Unique:** `(chain_id, transaction_hash)`
|
|
**Indexes:** `(chain_id, transaction_hash)`, `(chain_id, block_number)`
|
|
|
|
---
|
|
|
|
## 5. Logs
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| chain_id | integer | yes | EVM chain ID |
|
|
| transaction_hash | string(66) | yes | Transaction hash |
|
|
| block_number | bigint | yes | Block number |
|
|
| block_hash | string(66) | yes | Block hash |
|
|
| log_index | integer | yes | Index within transaction |
|
|
| address | string(42) | yes | Contract address |
|
|
| topic0 | string(66) | no | Event signature hash |
|
|
| topic1 | string(66) | no | First indexed parameter |
|
|
| topic2 | string(66) | no | Second indexed parameter |
|
|
| topic3 | string(66) | no | Third indexed parameter |
|
|
| data | string | no | Non-indexed data (hex) |
|
|
| created_at | string (ISO8601) | yes | Ingestion timestamp |
|
|
|
|
**Unique:** `(chain_id, transaction_hash, log_index)`
|
|
**Indexes:** `(chain_id, transaction_hash)`, `(chain_id, address)`, `(chain_id, topic0)`, `(chain_id, block_number)`, `(chain_id, address, topic0)`
|
|
|
|
---
|
|
|
|
## 6. Decoded events
|
|
|
|
Decoded view of logs when ABI is available. Used for indexing and for commitment leaf payload hash.
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| chain_id | integer | yes | EVM chain ID |
|
|
| transaction_hash | string(66) | yes | Transaction hash |
|
|
| block_number | bigint | yes | Block number |
|
|
| log_index | integer | yes | Log index |
|
|
| address | string(42) | yes | Contract address |
|
|
| event_signature | string | yes | e.g. Transfer(address,address,uint256) |
|
|
| event_name | string | yes | e.g. Transfer |
|
|
| decoded_params | object | yes | Key-value of decoded parameters |
|
|
| payload_hash | string(66) | no | keccak256(canonical_json(decoded_params)) for commitment leaf |
|
|
| created_at | string (ISO8601) | yes | Ingestion timestamp |
|
|
|
|
**Unique:** `(chain_id, transaction_hash, log_index)`
|
|
**Indexes:** `(chain_id, address)`, `(chain_id, event_name)`, `(chain_id, block_number)`
|
|
|
|
**Canonical encoding for payload_hash:** Sort keys of `decoded_params` alphabetically; encode as JSON without whitespace; hash with keccak256.
|
|
|
|
---
|
|
|
|
## 7. Execution steps
|
|
|
|
Links intents/executions to on-chain transactions. Used by EO and for SAL reconciliation.
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| execution_id | string(UUID) | yes | Execution run ID |
|
|
| intent_id | string(UUID) | yes | Intent ID |
|
|
| step_index | integer | yes | Order of step (0-based) |
|
|
| step_type | string | yes | transfer, swap, bridge, message_send, message_receive, mint, burn |
|
|
| chain_id | integer | yes | Chain where tx was submitted |
|
|
| transaction_hash | string(66) | no | Tx hash once submitted |
|
|
| status | string | yes | pending, submitted, confirmed, finalized, failed |
|
|
| preconditions | string | no | JSON array of precondition IDs |
|
|
| postconditions | string | no | JSON array of postcondition IDs |
|
|
| gas_used | bigint | no | Filled after confirmation |
|
|
| created_at | string (ISO8601) | yes | Created timestamp |
|
|
| updated_at | string (ISO8601) | yes | Last update |
|
|
|
|
**Unique:** `(execution_id, step_index)`
|
|
**Indexes:** `(execution_id)`, `(intent_id)`, `(chain_id, transaction_hash)`, `(status)`
|
|
|
|
---
|
|
|
|
## 8. SAL journal entry hash (optional for commitment leaf)
|
|
|
|
For Merkle commitment leaves, a leaf may include the hash of the SAL journal entry that corresponds to this transaction (if any). Schema for the hash input:
|
|
|
|
- **Input to hash:** `ledger_id || entry_id || debit_account_id || credit_account_id || amount || currency_code || reference_id || timestamp_utc`
|
|
- **Encoding:** Concatenate as UTF-8 strings with a single delimiter (e.g. `|`); then keccak256.
|
|
- **Field in commitment leaf:** `sal_journal_entry_hash` (bytes32), optional; null if no ledger entry.
|
|
|
|
---
|
|
|
|
## 9. Commitment leaf (Merkle tree)
|
|
|
|
Each leaf in the mirroring Merkle tree is built from:
|
|
|
|
| Field | Source | Description |
|
|
|-------|--------|-------------|
|
|
| tx_hash | transactions.hash | Transaction hash |
|
|
| block_number | blocks.number | Block number |
|
|
| receipt_root or logs_bloom | receipts / blocks | Receipt root or logs bloom (chain-dependent) |
|
|
| normalized_event_payload_hash | decoded_events.payload_hash | Hash of decoded event payload (or logs hash if no decode) |
|
|
| sal_journal_entry_hash | ledger_entries | Optional; from SAL if applicable |
|
|
|
|
**Leaf encoding (canonical):** `keccak256(abi.encodePacked(chain_id, tx_hash, block_number, receipt_root_or_logs_bloom, normalized_event_payload_hash, sal_journal_entry_hash))`
|
|
Schema version and chain_id are also stored at commit level (startBlock, endBlock, root, chain_id, schema_version).
|
|
|
|
---
|
|
|
|
## 10. Changelog
|
|
|
|
| Version | Date | Change |
|
|
|---------|------|--------|
|
|
| 1.0 | 2026-01-28 | Initial normalized event schema v1 for EII, SAL, and Mirroring. |
|