@ottochain/sdk 2.2.4 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/cjs/apps/contracts/state-machines/contract-agreement.js +54 -6
  2. package/dist/cjs/apps/contracts/state-machines/contract-escrow.js +72 -8
  3. package/dist/cjs/apps/contracts/state-machines/contract-universal.js +36 -4
  4. package/dist/cjs/apps/governance/state-machines/dao-multisig.js +27 -3
  5. package/dist/cjs/apps/governance/state-machines/dao-reputation.js +27 -3
  6. package/dist/cjs/apps/governance/state-machines/dao-single.js +27 -3
  7. package/dist/cjs/apps/governance/state-machines/dao-token.js +36 -4
  8. package/dist/cjs/apps/governance/state-machines/governance-simple.js +36 -4
  9. package/dist/cjs/apps/governance/state-machines/governance-universal.js +27 -3
  10. package/dist/cjs/apps/identity/state-machines/identity-agent.js +54 -6
  11. package/dist/cjs/apps/identity/state-machines/identity-oracle.js +45 -5
  12. package/dist/cjs/apps/identity/state-machines/identity-universal.js +27 -3
  13. package/dist/cjs/apps/markets/state-machines/market-auction.js +30 -6
  14. package/dist/cjs/apps/markets/state-machines/market-crowdfund.js +25 -5
  15. package/dist/cjs/apps/markets/state-machines/market-group-buy.js +29 -5
  16. package/dist/cjs/apps/markets/state-machines/market-prediction.js +40 -8
  17. package/dist/cjs/apps/markets/state-machines/market-universal.js +45 -5
  18. package/dist/cjs/generated/ottochain/v1/common.js +1722 -1
  19. package/dist/cjs/generated/ottochain/v1/fiber.js +352 -2
  20. package/dist/cjs/generated/ottochain/v1/messages.js +775 -3
  21. package/dist/cjs/generated/ottochain/v1/records.js +350 -3
  22. package/dist/cjs/index.js +5 -1
  23. package/dist/cjs/ottochain/genesis-manifest.js +193 -0
  24. package/dist/cjs/ottochain/index.js +5 -1
  25. package/dist/cjs/ottochain/normalize.js +26 -48
  26. package/dist/cjs/ottochain/types.js +4 -0
  27. package/dist/esm/apps/contracts/state-machines/contract-agreement.js +54 -6
  28. package/dist/esm/apps/contracts/state-machines/contract-escrow.js +72 -8
  29. package/dist/esm/apps/contracts/state-machines/contract-universal.js +36 -4
  30. package/dist/esm/apps/governance/state-machines/dao-multisig.js +27 -3
  31. package/dist/esm/apps/governance/state-machines/dao-reputation.js +27 -3
  32. package/dist/esm/apps/governance/state-machines/dao-single.js +27 -3
  33. package/dist/esm/apps/governance/state-machines/dao-token.js +36 -4
  34. package/dist/esm/apps/governance/state-machines/governance-simple.js +36 -4
  35. package/dist/esm/apps/governance/state-machines/governance-universal.js +27 -3
  36. package/dist/esm/apps/identity/state-machines/identity-agent.js +54 -6
  37. package/dist/esm/apps/identity/state-machines/identity-oracle.js +45 -5
  38. package/dist/esm/apps/identity/state-machines/identity-universal.js +27 -3
  39. package/dist/esm/apps/markets/state-machines/market-auction.js +30 -6
  40. package/dist/esm/apps/markets/state-machines/market-crowdfund.js +25 -5
  41. package/dist/esm/apps/markets/state-machines/market-group-buy.js +29 -5
  42. package/dist/esm/apps/markets/state-machines/market-prediction.js +40 -8
  43. package/dist/esm/apps/markets/state-machines/market-universal.js +45 -5
  44. package/dist/esm/generated/ottochain/v1/common.js +1718 -0
  45. package/dist/esm/generated/ottochain/v1/fiber.js +351 -1
  46. package/dist/esm/generated/ottochain/v1/messages.js +774 -2
  47. package/dist/esm/generated/ottochain/v1/records.js +349 -2
  48. package/dist/esm/index.js +2 -0
  49. package/dist/esm/ottochain/genesis-manifest.js +189 -0
  50. package/dist/esm/ottochain/index.js +2 -0
  51. package/dist/esm/ottochain/normalize.js +26 -48
  52. package/dist/esm/ottochain/types.js +4 -0
  53. package/dist/types/apps/contracts/index.d.ts +90 -18
  54. package/dist/types/apps/contracts/state-machines/contract-agreement.d.ts +30 -6
  55. package/dist/types/apps/contracts/state-machines/contract-escrow.d.ts +40 -8
  56. package/dist/types/apps/contracts/state-machines/contract-universal.d.ts +20 -4
  57. package/dist/types/apps/governance/index.d.ts +114 -33
  58. package/dist/types/apps/governance/state-machines/dao-multisig.d.ts +15 -3
  59. package/dist/types/apps/governance/state-machines/dao-reputation.d.ts +15 -3
  60. package/dist/types/apps/governance/state-machines/dao-single.d.ts +15 -3
  61. package/dist/types/apps/governance/state-machines/dao-token.d.ts +20 -4
  62. package/dist/types/apps/governance/state-machines/governance-simple.d.ts +20 -4
  63. package/dist/types/apps/governance/state-machines/governance-universal.d.ts +15 -3
  64. package/dist/types/apps/identity/index.d.ts +71 -6
  65. package/dist/types/apps/identity/state-machines/identity-agent.d.ts +30 -0
  66. package/dist/types/apps/identity/state-machines/identity-oracle.d.ts +25 -0
  67. package/dist/types/apps/identity/state-machines/identity-universal.d.ts +15 -0
  68. package/dist/types/apps/markets/index.d.ts +80 -5
  69. package/dist/types/apps/markets/state-machines/market-auction.d.ts +12 -0
  70. package/dist/types/apps/markets/state-machines/market-crowdfund.d.ts +10 -0
  71. package/dist/types/apps/markets/state-machines/market-group-buy.d.ts +14 -0
  72. package/dist/types/apps/markets/state-machines/market-prediction.d.ts +16 -0
  73. package/dist/types/apps/markets/state-machines/market-universal.d.ts +25 -5
  74. package/dist/types/generated/ottochain/v1/common.d.ts +228 -0
  75. package/dist/types/generated/ottochain/v1/fiber.d.ts +32 -1
  76. package/dist/types/generated/ottochain/v1/messages.d.ts +84 -0
  77. package/dist/types/generated/ottochain/v1/records.d.ts +34 -0
  78. package/dist/types/index.d.ts +3 -1
  79. package/dist/types/ottochain/genesis-manifest.d.ts +130 -0
  80. package/dist/types/ottochain/index.d.ts +3 -1
  81. package/dist/types/ottochain/normalize.d.ts +17 -25
  82. package/dist/types/ottochain/types.d.ts +288 -2
  83. package/dist/types/schema/fiber-app.d.ts +40 -1
  84. package/dist/types/validation.d.ts +17 -17
  85. package/package.json +30 -27
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Genesis Manifest Exporter
3
+ *
4
+ * The ottochain metagraph can boot from a NON-EMPTY genesis: a set of standard
5
+ * packages pre-registered in the registry before any user transaction. This SDK
6
+ * is the source of truth for those std apps (their proto schemas + JSON-Logic
7
+ * state-machine definitions), so it is also the source of truth for the
8
+ * *genesis manifest* — the per-app CONTENT the chain needs to pre-register each
9
+ * package at genesis.
10
+ *
11
+ * DESIGN — content, not consensus hashes:
12
+ * The manifest ships CONTENT only: the `schemaShape` (the typed, proto-faithful
13
+ * projection of the app's state message) and the `definition` (the JSON-Logic
14
+ * `StateMachineDefinition`, verbatim — the same object the chain decodes for any
15
+ * fiber). The CHAIN computes the consensus values itself from this content:
16
+ * - `logicHash` = `StateMachineDefinition.computeDigest(definition)`
17
+ * - `schemaHash` = commitment over the FileDescriptorSet (off-chain/Bridge)
18
+ * We deliberately do NOT replicate the chain's canonical hashing here, so there
19
+ * is ZERO hash-parity risk. No advisory hashes are emitted (see HONESTY notes in
20
+ * the PR description); add them later only if an off-chain consumer needs them,
21
+ * clearly marked advisory.
22
+ *
23
+ * NAMING — the reserved `std` label:
24
+ * Each package is named `std.<app>.package`. `RegistryName` reserves the `std`
25
+ * label in-protocol (`RegistryName.isReserved`), so ordinary user registrations
26
+ * of `std.*` are rejected — only the privileged genesis path may claim them.
27
+ * That is exactly the point: users cannot squat the standard names.
28
+ *
29
+ * SCHEMA SHAPES — chain-verified ground truth:
30
+ * The three `stateMessage` shapes are reproduced verbatim from the chain's own
31
+ * conformance suite (`StandardAppsConformanceSuite`, the `identity` / `proposal`
32
+ * / `market` `MessageShape` vals), which proves the on-chain shape validator and
33
+ * the conformance gate accept them. `commands` is left EMPTY for this first cut —
34
+ * the conformance suite itself models all three apps with `SortedMap.empty`
35
+ * commands, and the proto `*Request` messages are transaction-layer DTOs that do
36
+ * not map cleanly onto the universal state machines' free-form JSON-Logic event
37
+ * payloads. Deriving per-event command shapes is a flagged follow-up.
38
+ *
39
+ * The JSON shape emitted here is built to deserialize against the chain's circe
40
+ * codecs (`SchemaShape` / `FieldShape` / `MessageShape` and
41
+ * `StateMachineDefinition`), whose magnolia config is camelCase with defaults.
42
+ *
43
+ * @packageDocumentation
44
+ */
45
+ /**
46
+ * One field of a protobuf message, mirroring a `FieldDescriptorProto` at the
47
+ * field level. Matches the chain's `FieldShape` (camelCase, defaults for
48
+ * `repeated`/`optional`).
49
+ */
50
+ export interface FieldShape {
51
+ name: string;
52
+ number: number;
53
+ typeName: string;
54
+ repeated: boolean;
55
+ optional: boolean;
56
+ }
57
+ /** A protobuf message projection. Matches the chain's `MessageShape`. */
58
+ export interface MessageShape {
59
+ typeName: string;
60
+ fields: FieldShape[];
61
+ }
62
+ /**
63
+ * The typed, proto-faithful projection of a registered schema. Matches the
64
+ * chain's `SchemaShape`: the state message plus one message per command/event,
65
+ * keyed by event name.
66
+ */
67
+ export interface SchemaShape {
68
+ stateMessage: MessageShape;
69
+ commands: Record<string, MessageShape>;
70
+ }
71
+ /**
72
+ * A JSON-Logic `StateMachineDefinition` as the chain decodes it. Kept as an
73
+ * opaque JSON object: the chain owns its meaning and its hashing. `from`/`to`
74
+ * and the `states` keys are bare strings (the chain's `StateId` encodes as a
75
+ * string); `dependencies` defaults to `[]` and state `metadata` to `null`.
76
+ */
77
+ export interface StateMachineDefinition {
78
+ states: Record<string, {
79
+ id: string;
80
+ isFinal: boolean;
81
+ metadata: unknown | null;
82
+ }>;
83
+ initialState: string;
84
+ transitions: Array<{
85
+ from: string;
86
+ to: string;
87
+ eventName: string;
88
+ guard: unknown;
89
+ effect: unknown;
90
+ dependencies: unknown[];
91
+ }>;
92
+ metadata: unknown | null;
93
+ }
94
+ /**
95
+ * One package to pre-register at genesis. This is the genesis INPUT, not the
96
+ * chain's stored `RegisteredVersion`: it carries CONTENT only and the chain
97
+ * derives `schemaHash` / `logicHash` from it.
98
+ */
99
+ export interface GenesisPackage {
100
+ /** RegistryName `"<labels>.package"`, e.g. `std.identity.package`. */
101
+ name: string;
102
+ /** SemVer of this initial version. */
103
+ semver: string;
104
+ /** Opt-in runtime conformance gate (`RegisteredVersion.strict`). */
105
+ strict: boolean;
106
+ /** Free-form notes map (<=8 entries, key <=32 chars, value <=128 chars). */
107
+ metadata: Record<string, string>;
108
+ /** Typed, proto-faithful projection of the app's schema. */
109
+ schemaShape: SchemaShape;
110
+ /** The JSON-Logic state-machine definition, verbatim. */
111
+ definition: StateMachineDefinition;
112
+ }
113
+ /** The full genesis manifest the chain consumes to bootstrap its registry. */
114
+ export interface GenesisManifest {
115
+ version: number;
116
+ packages: GenesisPackage[];
117
+ }
118
+ /** Manifest schema version. Bump on any breaking change to the shape. */
119
+ export declare const GENESIS_MANIFEST_VERSION = 1;
120
+ /**
121
+ * Assemble the genesis manifest for the standard apps.
122
+ *
123
+ * Covers THREE apps in this first cut — identity, governance, markets (all the
124
+ * `universal` variant). The other std apps (contracts, oracles, corporate) and
125
+ * non-universal variants are a flagged follow-up.
126
+ *
127
+ * @returns a `GenesisManifest` whose JSON deserializes against the chain's circe
128
+ * codecs. Hashes are intentionally absent — the chain derives them.
129
+ */
130
+ export declare function buildGenesisManifest(): GenesisManifest;
@@ -6,7 +6,7 @@
6
6
  * @packageDocumentation
7
7
  */
8
8
  export * as proto from '../generated/index.js';
9
- export type { Address, FiberId, StateId, HashValue, FiberOrdinal, SnapshotOrdinal, JsonLogicValue, JsonLogicExpression, FiberStatus, AccessControlPolicy, StateMachineDefinition, EmittedEvent, EventReceipt, OracleInvocation, FiberLogEntry, StateMachineFiberRecord, ScriptFiberRecord, FiberRecord, FiberCommit, OnChain, CalculatedState, CreateStateMachine, TransitionStateMachine, ArchiveStateMachine, CreateScript, InvokeScript, OttochainMessage, OttochainMessageType, } from './types.js';
9
+ export type { Address, FiberId, StateId, HashValue, FiberOrdinal, SnapshotOrdinal, JsonLogicValue, JsonLogicExpression, FiberStatus, AccessControlPolicy, StateMachineDefinition, SemVer, RegistryStatus, VersionReq, SchemaRef, FieldShape, MessageShape, SchemaShape, SchemaBinding, RegisteredVersion, VersionLineage, RegistryTarget, RegistryEntry, EmittedEvent, EventReceipt, OracleInvocation, CreationReceipt, UpgradeReceipt, FiberLogEntry, StateMachineFiberRecord, ScriptFiberRecord, FiberRecord, FiberCommit, OnChain, CalculatedState, CreateStateMachine, TransitionStateMachine, ArchiveStateMachine, UpgradeFiber, CreateScript, InvokeScript, PublishVersion, SetVersionStatus, RegisterAlias, OttochainMessage, OttochainMessageType, } from './types.js';
10
10
  export { OTTOCHAIN_MESSAGE_TYPES } from './types.js';
11
11
  export type { CurrencySnapshotResponse } from './snapshot.js';
12
12
  export { decodeOnChainState, getSnapshotOnChainState, getLatestOnChainState, getLogsForFiber, getEventReceipts, getScriptInvocations, extractOnChainState, } from './snapshot.js';
@@ -16,3 +16,5 @@ export { createTransitionPayload, createArchivePayload, createInvokeScriptPayloa
16
16
  export type { CreateStateMachineParams, CreateStateMachineMessage, CreateScriptParams, CreateScriptMessage, DataTransactionRequest, TransitionParams, TransitionStateMachineMessage, ArchiveParams, ArchiveStateMachineMessage, InvokeScriptParams, InvokeScriptMessage, } from './transaction.js';
17
17
  export { normalizeCreateStateMachine, normalizeTransitionStateMachine, normalizeArchiveStateMachine, normalizeMessage, } from './normalize.js';
18
18
  export { dropNulls } from './drop-nulls.js';
19
+ export { buildGenesisManifest, GENESIS_MANIFEST_VERSION } from './genesis-manifest.js';
20
+ export type { GenesisManifest, GenesisPackage, SchemaShape as GenesisSchemaShape, MessageShape as GenesisMessageShape, FieldShape as GenesisFieldShape, StateMachineDefinition as GenesisStateMachineDefinition, } from './genesis-manifest.js';
@@ -2,46 +2,38 @@
2
2
  * Normalize OttoChain Messages for Signing
3
3
  *
4
4
  * Converts OttoChain message objects to the wire format expected by the
5
- * Scala metagraph. Metakit's JsonBinaryCodec (used by OttoChain for data
6
- * transaction signing) canonicalizes JSON with dropNullValues = true.
5
+ * Scala metagraph. Specifically, ensures all `Option[A]=None` fields are
6
+ * present as explicit `null` values, matching what circe's magnolia encoder
7
+ * produces on the Scala side.
7
8
  *
8
- * NOTE: This is Metakit's codec, NOT tessellation's JsonSerializer (which
9
- * uses Brotli compression for snapshots/consensus a different layer).
10
- * Different layers use different byte-sequence encoders.
9
+ * This is necessary because metakit's `JsonBinaryCodec.deriveDataUpdate`
10
+ * (rc.8) canonicalizes the circe-encoded JSON **including null fields**.
11
+ * If the TypeScript client omits optional fields (undefined), the canonical
12
+ * JSON won't match and signature verification will fail.
11
13
  *
12
- * Because Metakit drops null fields during canonicalization, the canonical
13
- * JSON used for signature verification **omits** null fields entirely.
14
- * If the TypeScript client includes explicit nulls (e.g., `"metadata": null`),
15
- * the canonical form won't match and signature verification will fail.
16
- *
17
- * Schema mapping (Scala → TypeScript wire format):
18
- * - `Option[A] = None` → field OMITTED (not null, not undefined)
14
+ * Schema mapping (Scala TypeScript):
15
+ * - `Option[A] = None` `null` (must be explicit, not undefined/absent)
19
16
  * - `Option[A] = Some(v)` → `v`
20
- * - `List.empty` / `Set.empty` → `[]`
17
+ * - `List.empty` → `[]`
21
18
  * - `Map.empty` → `{}`
22
- * - `Boolean = false` → `false` (always include, not a null/Option)
23
19
  */
24
20
  /**
25
21
  * Normalize a CreateStateMachine message for wire format
26
22
  *
27
- * Metakit's JsonBinaryCodec uses dropNullValues = true for canonicalization.
28
- * Optional fields at their defaults must be OMITTED (not set to null)
29
- * to match the canonical JSON used for signature verification.
30
- *
31
- * - definition.metadataOMITTED when absent/FiberAppMetadata
32
- * - definition.states[*].metadata → OMITTED when absent
33
- * - definition.transitions[*].dependencies → [] (Set.empty default, always included)
34
- * - parentFiberId → OMITTED when absent (Option[UUID] = None)
35
- * - participants → OMITTED when absent (Option[Set[Address]] = None)
23
+ * Ensures all Option/default fields are explicit in wire format:
24
+ * - definition.metadata null when absent
25
+ * - definition.states[*].metadata null when absent
26
+ * - definition.transitions[*].dependencies → [] when absent
27
+ * - parentFiberIdnull when absent
36
28
  *
37
29
  * @example
38
30
  * ```typescript
39
31
  * const message = normalizeCreateStateMachine({
40
32
  * fiberId: '...',
41
- * definition: { states: { INIT: { id: 'INIT', isFinal: false } }, ... },
33
+ * definition: { states: { INIT: { id: { value: 'INIT' }, isFinal: false } }, ... },
42
34
  * initialData: {}
43
35
  * });
44
- * // Optional fields are absent (not null): no parentFiberId, no metadata, etc.
36
+ * // message now has parentFiberId: null, definition.metadata: null, etc.
45
37
  * ```
46
38
  */
47
39
  export declare function normalizeCreateStateMachine(msg: Record<string, unknown>): Record<string, unknown>;
@@ -46,6 +46,183 @@ export interface StateMachineDefinition {
46
46
  transitions: unknown[];
47
47
  metadata?: JsonLogicValue;
48
48
  }
49
+ /**
50
+ * Semantic version `MAJOR.MINOR.PATCH`.
51
+ * Wire format: plain string (e.g. "1.0.0"). Also used as a JSON map key.
52
+ *
53
+ * @see modules/models/.../schema/registry/SemVer.scala
54
+ */
55
+ export type SemVer = string;
56
+ /**
57
+ * Lifecycle status of a registered version (npm/Cargo-style).
58
+ * Wire format: uppercase string (enumeratum `Uppercase`).
59
+ *
60
+ * - `ACTIVE` — selectable + recommended.
61
+ * - `DEPRECATED` — still resolvable/runnable, flagged, discouraged for new instances.
62
+ * - `YANKED` — excluded from NEW resolutions; existing pinned fibers keep running.
63
+ *
64
+ * @see modules/models/.../schema/registry/RegistryStatus.scala
65
+ */
66
+ export type RegistryStatus = 'ACTIVE' | 'DEPRECATED' | 'YANKED';
67
+ /**
68
+ * A caller's version requirement, resolved against a {@link VersionLineage} (Cargo/npm-style).
69
+ * Wire format: single-key wrapper object (sealed-trait encoding).
70
+ *
71
+ * - `Exact` — exactly this version: `{"Exact":{"version":"1.0.0"}}`.
72
+ * - `Caret` — same MAJOR and `>= v` (`^1.2.0`).
73
+ * - `Tilde` — same MAJOR.MINOR and `>= v` (`~1.2.0`).
74
+ * - `Latest` — highest selectable version: `{"Latest":{}}`.
75
+ * - `PinnedHash` — the exact artifact by schema hash, version-agnostic.
76
+ *
77
+ * @see modules/models/.../schema/registry/VersionReq.scala
78
+ */
79
+ export type VersionReq = {
80
+ Exact: {
81
+ version: SemVer;
82
+ };
83
+ } | {
84
+ Caret: {
85
+ version: SemVer;
86
+ };
87
+ } | {
88
+ Tilde: {
89
+ version: SemVer;
90
+ };
91
+ } | {
92
+ Latest: Record<string, never>;
93
+ } | {
94
+ PinnedHash: {
95
+ schemaHash: string;
96
+ };
97
+ };
98
+ /**
99
+ * A caller's reference to a registered schema/program version, supplied at fiber creation
100
+ * (`CreateStateMachine.schemaRef`). The chain resolves `version` against the registry at create time.
101
+ * Wire format: `{"name":"counter.package","version":{"Exact":{"version":"1.0.0"}}}`.
102
+ *
103
+ * @see modules/models/.../schema/registry/SchemaRef.scala
104
+ */
105
+ export interface SchemaRef {
106
+ /** Full registry name `labels.tld` (e.g. "counter.package"). */
107
+ name: string;
108
+ version: VersionReq;
109
+ }
110
+ /**
111
+ * One field of a {@link MessageShape} — mirrors a protobuf `FieldDescriptorProto`
112
+ * at the field level (name + field number + type).
113
+ * Wire format: `repeated`/`optional` default to `false` and are omittable.
114
+ *
115
+ * @see modules/models/.../schema/registry/SchemaShape.scala
116
+ */
117
+ export interface FieldShape {
118
+ name: string;
119
+ number: number;
120
+ typeName: string;
121
+ repeated?: boolean;
122
+ optional?: boolean;
123
+ }
124
+ /**
125
+ * A single protobuf message shape: its type name plus its fields.
126
+ *
127
+ * @see modules/models/.../schema/registry/SchemaShape.scala
128
+ */
129
+ export interface MessageShape {
130
+ typeName: string;
131
+ fields: FieldShape[];
132
+ }
133
+ /**
134
+ * The on-chain projection of a version's proto schema: the State message plus one
135
+ * message per command/event (keyed by event name). Publisher-claimed and advisory.
136
+ *
137
+ * @see modules/models/.../schema/registry/SchemaShape.scala
138
+ */
139
+ export interface SchemaShape {
140
+ stateMessage: MessageShape;
141
+ /** One message per command/event, keyed by event name. */
142
+ commands: Record<string, MessageShape>;
143
+ }
144
+ /**
145
+ * The resolved, pinned binding recorded on a fiber: which registry (name, version) it
146
+ * instantiates, with the committed hashes. Resolved once at create, then immutable.
147
+ *
148
+ * @see modules/models/.../schema/registry/SchemaBinding.scala
149
+ */
150
+ export interface SchemaBinding {
151
+ /** Full registry name `labels.tld`. */
152
+ name: string;
153
+ version: SemVer;
154
+ /** Commitment to the protobuf FileDescriptorSet (descriptor bytes; off-chain). */
155
+ schemaHash: string;
156
+ /** The verified-binding anchor: `StateMachineDefinition.computeDigest` of the logic. */
157
+ logicHash: string;
158
+ }
159
+ /**
160
+ * One immutable version of a registry entry. The chain commits only the hashes + the
161
+ * typed {@link SchemaShape} projection (never the descriptor or definition bytes).
162
+ * Wire format: `strict` defaults to `false` and is omittable.
163
+ *
164
+ * @see modules/models/.../schema/registry/RegisteredVersion.scala
165
+ */
166
+ export interface RegisteredVersion {
167
+ version: SemVer;
168
+ /** Commitment to the protobuf FileDescriptorSet (descriptor bytes; off-chain). */
169
+ schemaHash: string;
170
+ /** The verified-binding anchor: `StateMachineDefinition.computeDigest` of the logic. */
171
+ logicHash: string;
172
+ schemaShape: SchemaShape;
173
+ status: RegistryStatus;
174
+ /** Snapshot ordinal at which this version was registered. */
175
+ registeredAt: number;
176
+ /** Opt-in runtime conformance gate (#33); defaults to `false`. */
177
+ strict?: boolean;
178
+ }
179
+ /**
180
+ * The append-only, monotonic version lineage of a single registry entry.
181
+ * Wire format: `versions` is a SemVer-string-keyed map of {@link RegisteredVersion}.
182
+ *
183
+ * @see modules/models/.../schema/registry/VersionLineage.scala
184
+ */
185
+ export interface VersionLineage {
186
+ /** SemVer-string keyed map of registered versions. */
187
+ versions: Record<string, RegisteredVersion>;
188
+ }
189
+ /**
190
+ * What a registry entry resolves to, discriminated by the name's TLD.
191
+ * Wire format: single-key wrapper object (sealed-trait encoding).
192
+ *
193
+ * - `SchemaPackage` (`.package`) — a versioned schema/program type (its {@link VersionLineage}).
194
+ * Note the double-nesting: `SchemaPackage.versions` is a {@link VersionLineage} whose
195
+ * own `.versions` is the SemVer-keyed map, e.g.
196
+ * `{"SchemaPackage":{"versions":{"versions":{"1.0.0":{...}}}}}`.
197
+ * - `InstanceAlias` (`.machine` / `.script`) — a nickname for an existing fiber (#29).
198
+ *
199
+ * @see modules/models/.../schema/registry/RegistryTarget.scala
200
+ */
201
+ export type RegistryTarget = {
202
+ SchemaPackage: {
203
+ versions: VersionLineage;
204
+ };
205
+ } | {
206
+ InstanceAlias: {
207
+ fiberId: string;
208
+ };
209
+ };
210
+ /**
211
+ * A single owned entry in the registry namespace: a name -> a discriminated
212
+ * {@link RegistryTarget}, with the owning addresses and an optional off-chain metadata grab-bag.
213
+ * Wire format: `metadata` defaults to `{}` and is omittable.
214
+ *
215
+ * @see modules/models/.../schema/registry/RegistryEntry.scala
216
+ */
217
+ export interface RegistryEntry {
218
+ /** Full registry name `labels.tld`. */
219
+ name: string;
220
+ /** Owning DAG addresses (who may publish versions / change status / transfer). */
221
+ owner: string[];
222
+ target: RegistryTarget;
223
+ /** Optional off-chain links grab-bag (e.g. "repo"/"homepage" -> URL). */
224
+ metadata?: Record<string, string>;
225
+ }
49
226
  /**
50
227
  * Event emitted by a state machine transition trigger.
51
228
  */
@@ -84,10 +261,40 @@ export interface OracleInvocation {
84
261
  invokedAt: number;
85
262
  invokedBy: string;
86
263
  }
264
+ /**
265
+ * Birth record for a fiber, emitted once at creation. Records the resolved registry
266
+ * binding (name@version + committed hashes) when instantiated from a registered version
267
+ * (#26), or omits it for an ad-hoc fiber. Seeds the audit-trail rendering (#30).
268
+ *
269
+ * @see modules/models/.../schema/fiber/FiberLogEntry.scala
270
+ */
271
+ export interface CreationReceipt {
272
+ fiberId: string;
273
+ ordinal: number;
274
+ initialState: string;
275
+ owners: string[];
276
+ schemaBinding?: SchemaBinding;
277
+ parentFiberId?: string;
278
+ }
279
+ /**
280
+ * Emitted when a fiber is upgraded to a different registered version (#27). Records the
281
+ * binding change (from -> to) and whether a state migration ran.
282
+ *
283
+ * @see modules/models/.../schema/fiber/FiberLogEntry.scala
284
+ */
285
+ export interface UpgradeReceipt {
286
+ fiberId: string;
287
+ ordinal: number;
288
+ /** Prior binding; absent for a fiber that had no registry binding before the upgrade. */
289
+ fromBinding?: SchemaBinding;
290
+ toBinding: SchemaBinding;
291
+ gasUsed: number;
292
+ migrated: boolean;
293
+ }
87
294
  /**
88
295
  * Union type for all fiber log entries.
89
296
  */
90
- export type FiberLogEntry = EventReceipt | OracleInvocation;
297
+ export type FiberLogEntry = EventReceipt | OracleInvocation | CreationReceipt | UpgradeReceipt;
91
298
  /**
92
299
  * On-chain record for a state machine fiber.
93
300
  * Wire format: all ordinals/states/hashes are plain primitives.
@@ -107,6 +314,8 @@ export interface StateMachineFiberRecord {
107
314
  lastReceipt?: EventReceipt;
108
315
  parentFiberId?: string;
109
316
  childFiberIds: string[];
317
+ /** The resolved, pinned registry binding (#26), present when created from a registered version. */
318
+ schemaBinding?: SchemaBinding;
110
319
  }
111
320
  /**
112
321
  * On-chain record for a script oracle fiber.
@@ -142,6 +351,8 @@ export interface FiberCommit {
142
351
  export interface OnChain {
143
352
  fiberCommits: Record<string, FiberCommit>;
144
353
  latestLogs: Record<string, FiberLogEntry[]>;
354
+ /** Per-registry-entry commitment hash, keyed by full registry name `labels.tld`. */
355
+ registryCommits: Record<string, string>;
145
356
  }
146
357
  /**
147
358
  * Full calculated state (served by ML0 /v1/ endpoints).
@@ -149,6 +360,10 @@ export interface OnChain {
149
360
  export interface CalculatedState {
150
361
  stateMachines: Record<string, StateMachineFiberRecord>;
151
362
  scripts: Record<string, ScriptFiberRecord>;
363
+ /** Registry namespace, keyed by full registry name `labels.tld`. */
364
+ registry: Record<string, RegistryEntry>;
365
+ /** Reverse records (#29): fiber UUID -> its canonical registered name. */
366
+ reverseNames: Record<string, string>;
152
367
  }
153
368
  /**
154
369
  * Create a new state machine fiber.
@@ -160,6 +375,11 @@ export interface CreateStateMachine {
160
375
  parentFiberId?: string | null;
161
376
  /** Optional set of DAG addresses authorized to sign transitions (multi-party signing). */
162
377
  participants?: string[] | null;
378
+ /**
379
+ * Optional reference to a registered schema/program version (#26). When present, the chain
380
+ * resolves it against the registry at create time and records the verified {@link SchemaBinding}.
381
+ */
382
+ schemaRef?: SchemaRef | null;
163
383
  }
164
384
  /**
165
385
  * Trigger a state machine transition.
@@ -195,6 +415,64 @@ export interface InvokeScript {
195
415
  args: JsonLogicValue;
196
416
  targetSequenceNumber: number;
197
417
  }
418
+ /**
419
+ * Upgrade an existing fiber to a different registered version of the SAME package (#27).
420
+ * The chain verifies `newDefinition` hashes to the target version's `logicHash`, applies the
421
+ * optional `migration` (a JSON-Logic transform of the prior state data), preserves the current
422
+ * state id, and re-pins the binding.
423
+ */
424
+ export interface UpgradeFiber {
425
+ fiberId: string;
426
+ targetRef: SchemaRef;
427
+ newDefinition: StateMachineDefinition;
428
+ /** Optional JSON-Logic transform applied to the prior state data during upgrade. */
429
+ migration?: JsonLogicExpression;
430
+ targetSequenceNumber: number;
431
+ }
432
+ /**
433
+ * Create-or-append a registry schema-package version (npm-publish semantics): the first publish
434
+ * for a name claims it and makes the signer the owner; later publishes require an existing owner.
435
+ *
436
+ * Note: `fiberId` is NOT on the wire — the chain derives the routing id from `name`.
437
+ */
438
+ export interface PublishVersion {
439
+ /** Full registry name `labels.tld` (e.g. "order.package"). */
440
+ name: string;
441
+ version: SemVer;
442
+ /** Base64 of the proto FileDescriptorSet; the chain base64-validates + hashes it, then drops the bytes. */
443
+ schemaB64: string;
444
+ /** The typed proto projection the chain stores for discovery (advisory). */
445
+ schemaShape: SchemaShape;
446
+ /** The typed JSON-Logic state machine; hashed into `logicHash` for verified binding (#37). */
447
+ definition: StateMachineDefinition;
448
+ /** Opt-in runtime conformance gate (#33); defaults to `false`, omittable. */
449
+ strict?: boolean;
450
+ /** Optional off-chain links grab-bag set on the entry at first publish; defaults to `{}`, omittable. */
451
+ metadata?: Record<string, string>;
452
+ }
453
+ /**
454
+ * Change a registered version's lifecycle status (Active <-> Deprecated -> Yanked). Owner-gated.
455
+ */
456
+ export interface SetVersionStatus {
457
+ /** Full registry name `labels.tld`. */
458
+ name: string;
459
+ version: SemVer;
460
+ status: RegistryStatus;
461
+ }
462
+ /**
463
+ * Register a human-readable nickname for an existing fiber (#29). The name's TLD must be
464
+ * `.machine` or `.script` and match the target fiber's kind; the signer must own the target.
465
+ *
466
+ * Note: `fiberId` is NOT on the wire — the chain derives the routing id from `name`.
467
+ */
468
+ export interface RegisterAlias {
469
+ /** Full registry name `labels.tld` (e.g. "my-escrow.machine"). */
470
+ name: string;
471
+ /** The existing fiber UUID this alias points at. */
472
+ targetFiberId: string;
473
+ /** Optional off-chain links grab-bag; defaults to `{}`, omittable. */
474
+ metadata?: Record<string, string>;
475
+ }
198
476
  /**
199
477
  * Union type for all ottochain messages.
200
478
  * JSON is wrapped as `{ MessageName: { ...fields } }`.
@@ -205,16 +483,24 @@ export type OttochainMessage = {
205
483
  TransitionStateMachine: TransitionStateMachine;
206
484
  } | {
207
485
  ArchiveStateMachine: ArchiveStateMachine;
486
+ } | {
487
+ UpgradeFiber: UpgradeFiber;
208
488
  } | {
209
489
  CreateScript: CreateScript;
210
490
  } | {
211
491
  InvokeScript: InvokeScript;
492
+ } | {
493
+ PublishVersion: PublishVersion;
494
+ } | {
495
+ SetVersionStatus: SetVersionStatus;
496
+ } | {
497
+ RegisterAlias: RegisterAlias;
212
498
  };
213
499
  /**
214
500
  * Names of all valid OttochainMessage types.
215
501
  * Use this for runtime validation (e.g., in API routes).
216
502
  */
217
- export declare const OTTOCHAIN_MESSAGE_TYPES: readonly ["CreateStateMachine", "TransitionStateMachine", "ArchiveStateMachine", "CreateScript", "InvokeScript"];
503
+ export declare const OTTOCHAIN_MESSAGE_TYPES: readonly ["CreateStateMachine", "TransitionStateMachine", "ArchiveStateMachine", "UpgradeFiber", "CreateScript", "InvokeScript", "PublishVersion", "SetVersionStatus", "RegisterAlias"];
218
504
  /**
219
505
  * Type representing valid message type names.
220
506
  */
@@ -40,11 +40,50 @@ export interface EventSchema {
40
40
  required?: readonly string[];
41
41
  properties?: Record<string, SchemaField>;
42
42
  }
43
+ /**
44
+ * Lifecycle category for a state — a small fixed vocabulary that lets UIs group
45
+ * and color states and lets analytics bucket fibers without app-specific logic.
46
+ *
47
+ * - `initial` — the machine's `initialState` (entry point)
48
+ * - `active` — a normal, operational, non-terminal state
49
+ * - `pending` — a transient state awaiting an action/condition/timeout
50
+ * - `terminal` — a final state (`isFinal: true`); the machine ends here
51
+ */
52
+ export type StateCategory = 'initial' | 'active' | 'pending' | 'terminal';
53
+ /**
54
+ * Standard per-state metadata convention for OttoChain std apps.
55
+ *
56
+ * This is the minimal, high-value block we attach to every standard state
57
+ * definition (instead of `metadata: null`). It is plain JSON, so it survives
58
+ * the client/server null-dropping canonicalization (only NULL fields are
59
+ * dropped; a populated object is kept and signed/verified identically on both
60
+ * sides). Custom apps may extend `StateDefinition.metadata` with extra keys.
61
+ *
62
+ * Fields:
63
+ * - `label` — short human-readable title for the state (e.g. "Active")
64
+ * - `description` — one-line explanation of what the state means
65
+ * - `category` — optional lifecycle hint (see {@link StateCategory})
66
+ */
67
+ export interface StdStateMetadata {
68
+ /** Short human-readable title, e.g. "Voting". */
69
+ label: string;
70
+ /** One-line description of what this state represents. */
71
+ description: string;
72
+ /** Optional lifecycle category hint for UIs / analytics. */
73
+ category?: StateCategory;
74
+ }
43
75
  export interface StateDefinition {
44
76
  id: string;
45
77
  isFinal: boolean;
46
78
  description?: string;
47
- metadata?: Record<string, unknown> | null;
79
+ /**
80
+ * Optional per-state metadata. Std apps populate the {@link StdStateMetadata}
81
+ * convention (`label` / `description` / `category`); custom apps may use any
82
+ * JSON object or `null`. NOTE: a `null` here is stripped from the signed wire
83
+ * form (the chain drops null object-fields), so prefer populated metadata or
84
+ * omit the field entirely.
85
+ */
86
+ metadata?: StdStateMetadata | Record<string, unknown> | null;
48
87
  }
49
88
  export type JsonLogicRule = Record<string, unknown>;
50
89
  export interface EmitSpec {