IntersectMBO / IntersectMBO/evolution-sdk

Declarative CBOR schema via annotations (CborId)

オープン
#189 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
enhancement
主要言語
TypeScript
スター
22
フォーク
30
平均マージ
5時間 29分
マージ済み PR(30日)
12

説明

## Summary

Replace hand-written `FromCDDL` transforms with declarative schema annotations that describe CBOR wire format directly on Effect Schema types.

## Motivation

Currently each module (TransactionBody, TransactionWitnessSet, Transaction, etc.) has:
- A `CDDLSchema` (intermediate CBOR AST type)
- A `FromCDDL` transform (hand-written 200-500 line encode/decode)
- A `FromCBORBytes` that composes `FromBytes` with `FromCDDL`

This creates a two-hop pipeline (`Uint8Array → CBOR AST → domain`) with a validation boundary that clones objects and strips Symbol metadata (e.g. `kEncoding` for encoding preservation).

## Proposal

A `CborId` Symbol annotation on Effect Schemas that carries CBOR layout metadata:

```ts
const CborId = Symbol.for("evolution/CborId")

const Address = Schema.Uint8ArrayFromSelf.annotations({
[CborId]: { tag: 259 }
})

const Value = Schema.Struct({
coin: Schema.BigIntFromSelf,
multiasset: Schema.optional(MultiAsset),
}).annotations({
[CborId]: { encoding: "array", fieldOrder: ["coin", "multiasset"] }
})

const TransactionOutput = Schema.Struct({
address: Address,
value: Value,
datum: Schema.optional(Datum),
scriptRef: Schema.optional(ScriptRef),
}).annotations({
[CborId]: { encoding: "map", keys: { address: 0n, value: 1n, datum: 2n, scriptRef: 3n } }
})
```

A generic CBOR codec engine reads `[CborId]` annotations to:
- Map struct fields to integer-keyed CBOR map entries or positional array slots
- Wrap values in CBOR tags (e.g. `#6.258` for sets)
- Handle optional fields (omit from map when undefined)
- Thread `kEncoding` preservation metadata automatically

## Benefits

- **Eliminates `FromCDDL`** — no hand-written encode/decode per module
- **Eliminates `CDDLSchema`** — domain schema IS the codec schema, no intermediate type
- **Encoding preservation is free** — single transform boundary, no clone/Symbol stripping
- **Self-documenting** — annotations describe the wire format directly
- **Less code** — TransactionBody goes from ~500 lines of transform to ~25 lines of annotated schema

## Scope

- Build `CborId` annotation types and codec engine in CBOR.ts (~200-400 lines)
- Convert all modules with FromCDDL transforms to use annotated schemas
- Handle edge cases: Tag-258 sets, redeemer map/array duality, nested maps, etc.
- Maintain backward compatibility with existing domain types

## Context

Discovered during CBOR encoding preservation work. The immediate fix (replacing `MapFromSelf`/`Tuple` CDDLSchemas with non-cloning `Schema.declare`) unblocks encoding preservation. This issue tracks the larger architectural improvement.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

まず、既存の CBOR.ts の実装と、TransactionBody、TransactionWitnessSet、Transaction などのモジュールにある FromCDDL 変換を読みます。そこで CborId アノテーションと汎用 codec エンジンを定義し、その後、tag-258 の set、redeemer の map/array の二重性、ネストされた map、オプショナルフィールド、後方互換性をカバーしながら、対象モジュールを変換します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
backend-api-design
issue の種類
リファクタリング
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。