midgard-ts is the TypeScript types and binary codec package for the Sundial L2 data model. It gives you precise TypeScript interfaces for every on-chain structure — blocks, transactions, deposit events, withdrawal events — along with encode/decode functions that round-trip those structures through Sundial’s custom static/dynamic binary format. It also ships Phase A (stateless) and Phase B (stateful) validation pipelines, the same ones the Sundial node’s mempool processor uses. Version 0.1.0 lives in the demo/midgard-ts folder of the sundial-monorepo workspace and is published as the workspace package midgard-ts.
Installation
midgard-ts is a workspace package — add it as a local dependency from inside the sundial-monorepo workspace:
Type Modules
types/block — Block and Header
A Sundial L2 Block comprises a 28-byte header hash, a Header with Merkle roots for each dataset, and a BlockBody containing four maps: UTxOs, transactions, deposits, and withdrawals.
types/transaction — Transactions
Each L2 Transaction carries a full TransactionBody (inputs, outputs, fee, and optional fields controlled by a bitmask) and a TransactionWitnessSet. A TransactionCompact replaces the full body and witness set with their hashes — used inside block headers and fraud proofs.
types/events — Deposit and Withdrawal Events
DepositInfo and WithdrawalInfo are the payload types for L2 user events. Both have full representations (raw bytes) and compact representations (hashed) used in block headers.
Validation Modules
Phase A — Stateless Validation
Phase A validates each transaction independently against its own structure. No UTxO state is required. All checks are synchronous and safe to run in parallel. It enforces the following rules:Phase A rule set
Phase A rule set
| Rule | Description | |---|---| | R2 | Transaction hash integrity — computed
body hash must match declared txId | | R3 | Unsupported fields absent — no
redeemers, plutus_v3_scripts, or script_data_hash | | R4 | At least one
spend input | | R5 | No duplicate inputs within a single transaction | | R6 |
Output structure valid — non-negative coin, no overflow | | R9 | Validity
interval well-formed — validity_interval_start ≤ ttl | | R11 | Minimum fee
— measured against the CBOR-encoded transaction size | | R13 | Required
signers have corresponding vkey witnesses | | R14 | vkey witness signatures
verify against the transaction body hash | | R15 | Native scripts present and
valid against the validity interval | | R19 | is_valid must be true | |
R20 | No auxiliary data hash | | R23 | No minting | | R24 | network_id
matches the configured network when present |Phase B — Stateful Validation
Phase B validates Phase-A-accepted candidates against the current UTxO set. It builds a dependency graph, detects cycles, and processes transactions in topological waves with conflict-bucket parallelism. It enforces:Phase B rule set
Phase B rule set
| Rule | Description | |---|---| | R7 | Every spend input exists in the UTxO
state or is produced by an earlier accepted tx in the same batch | | R8 | No
double-spend across accepted transactions | | R8b | Every reference input
exists in UTxO state and is not spent by the same transaction | | R10 |
Validity interval is compatible with the current slot | | R12 | Value
preservation: Σ(inputs) − fee = Σ(outputs) | | R16 | Input-witness
consistency: pubkey inputs need vkey witnesses; script inputs need native
script witnesses | | R17 | No dependency cycles between transactions in the
batch | | R18 | Cascade-reject all descendants of any rejected transaction |
Block Inspection Utilities
Theinspect module provides a high-level validation helper for individual transactions supplied as CBOR hex. It decodes the CBOR, converts to the Midgard wire format, runs Phase A, and returns structural metadata alongside the validation result.
Binary Codec
midgard-ts uses a custom static/dynamic binary format for all on-chain structures. Each type exposes matching encode* and decode* functions.
Full codec function reference
Full codec function reference
The
midgard-ts binary format uses an 8-byte-aligned static/dynamic split —
every field’s fixed-size portion is written first, followed by variable-length
data. This is distinct from standard CBOR encoding and is intentionally
larger. Phase A’s minimum-fee check uses the CBOR size, not the Midgard binary
size, to match L1 protocol parameters correctly.Aiken Alignment
midgard-ts types mirror the Sundial on-chain Aiken smart contract data structures. When building off-chain tooling that constructs fraud proofs or state-queue operations, use midgard-ts to produce correctly shaped datums and redeemers that match the Plutus V3 validators.
Related Pages
Midgard SDK
The full transaction-building SDK for Sundial L2 — deposits, withdrawals,
transaction orders, and fraud proofs on the L1 settlement layer.
REST API Overview
Submit transactions and query L2 state via the Sundial node’s HTTP RPC API
without the SDK.