@ottochain/sdk 2.4.0 → 2.6.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 (227) hide show
  1. package/dist/cjs/apps/compute/index.js +33 -0
  2. package/dist/cjs/apps/compute/state-machines/compute-rule110.js +164 -0
  3. package/dist/cjs/apps/compute/state-machines/index.js +9 -0
  4. package/dist/cjs/apps/contracts/index.js +1 -1
  5. package/dist/cjs/apps/contracts/state-machines/contract-agreement.js +126 -148
  6. package/dist/cjs/apps/contracts/state-machines/contract-escrow.js +153 -174
  7. package/dist/cjs/apps/contracts/state-machines/contract-universal.js +46 -58
  8. package/dist/cjs/apps/corporate/state-machines/corp-board.js +415 -481
  9. package/dist/cjs/apps/corporate/state-machines/corp-entity.js +368 -440
  10. package/dist/cjs/apps/corporate/state-machines/corp-securities.js +532 -647
  11. package/dist/cjs/apps/corporate/state-machines/corp-shareholders.js +499 -603
  12. package/dist/cjs/apps/governance/index.js +7 -7
  13. package/dist/cjs/apps/governance/state-machines/dao-multisig.js +170 -209
  14. package/dist/cjs/apps/governance/state-machines/dao-reputation.js +161 -214
  15. package/dist/cjs/apps/governance/state-machines/dao-single.js +92 -92
  16. package/dist/cjs/apps/governance/state-machines/dao-token.js +169 -223
  17. package/dist/cjs/apps/governance/state-machines/governance-simple.js +185 -217
  18. package/dist/cjs/apps/governance/state-machines/governance-universal.js +64 -64
  19. package/dist/cjs/apps/identity/constants.js +16 -24
  20. package/dist/cjs/apps/identity/index.js +1 -1
  21. package/dist/cjs/apps/identity/state-machines/identity-agent.js +124 -158
  22. package/dist/cjs/apps/identity/state-machines/identity-oracle.js +151 -169
  23. package/dist/cjs/apps/identity/state-machines/identity-registry.js +89 -115
  24. package/dist/cjs/apps/identity/state-machines/identity-universal.js +51 -57
  25. package/dist/cjs/apps/index.js +4 -1
  26. package/dist/cjs/apps/lending/assets.js +41 -17
  27. package/dist/cjs/apps/lending/credit-scoring.js +4 -4
  28. package/dist/cjs/apps/lending/eligibility.js +9 -25
  29. package/dist/cjs/apps/lending/index.js +1 -1
  30. package/dist/cjs/apps/lending/state-machines/lending-zk-loan.js +177 -156
  31. package/dist/cjs/apps/markets/index.js +1 -1
  32. package/dist/cjs/apps/markets/state-machines/market-auction.js +115 -134
  33. package/dist/cjs/apps/markets/state-machines/market-crowdfund.js +122 -137
  34. package/dist/cjs/apps/markets/state-machines/market-group-buy.js +158 -177
  35. package/dist/cjs/apps/markets/state-machines/market-prediction.js +193 -227
  36. package/dist/cjs/apps/markets/state-machines/market-universal.js +65 -80
  37. package/dist/cjs/apps/oracles/index.js +1 -1
  38. package/dist/cjs/apps/privacy/index.js +67 -0
  39. package/dist/cjs/apps/privacy/state-machines/index.js +17 -0
  40. package/dist/cjs/apps/privacy/state-machines/mixer-ddhRing.js +286 -0
  41. package/dist/cjs/apps/privacy/state-machines/note-pool.js +476 -0
  42. package/dist/cjs/apps/staked-pool/assets.js +103 -0
  43. package/dist/cjs/apps/staked-pool/base.js +498 -0
  44. package/dist/cjs/apps/staked-pool/consumer.js +55 -0
  45. package/dist/cjs/apps/staked-pool/index.js +83 -0
  46. package/dist/cjs/apps/staked-pool/state-machines/index.js +12 -0
  47. package/dist/cjs/apps/staked-pool/state-machines/staked-pool-base.js +49 -0
  48. package/dist/cjs/apps/staked-pool/state-machines/staked-pool-oracle.js +131 -0
  49. package/dist/cjs/generated/google/protobuf/struct.js +1 -1
  50. package/dist/cjs/generated/google/protobuf/timestamp.js +1 -1
  51. package/dist/cjs/generated/ottochain/apps/contracts/v1/contract.js +1 -1
  52. package/dist/cjs/generated/ottochain/apps/corporate/v1/corporate.js +1 -1
  53. package/dist/cjs/generated/ottochain/apps/governance/v1/governance.js +1 -1
  54. package/dist/cjs/generated/ottochain/apps/identity/v1/attestation.js +1 -1
  55. package/dist/cjs/generated/ottochain/apps/identity/v1/identity.js +1 -1
  56. package/dist/cjs/generated/ottochain/apps/markets/v1/market.js +1 -1
  57. package/dist/cjs/generated/ottochain/v1/common.js +1 -1
  58. package/dist/cjs/generated/ottochain/v1/fiber.js +40 -2
  59. package/dist/cjs/generated/ottochain/v1/messages.js +1 -1
  60. package/dist/cjs/generated/ottochain/v1/records.js +1 -1
  61. package/dist/cjs/index.js +21 -3
  62. package/dist/cjs/ottochain/genesis-manifest.js +6 -0
  63. package/dist/cjs/ottochain/metagraph-client.js +63 -11
  64. package/dist/cjs/ottochain/snapshot.js +2 -4
  65. package/dist/cjs/ottochain/transaction.js +10 -0
  66. package/dist/cjs/privacy/sealed-bid.js +85 -82
  67. package/dist/cjs/privacy/shield-app.js +32 -32
  68. package/dist/cjs/schema/effects.js +145 -1
  69. package/dist/cjs/schema/fiber-app.js +139 -5
  70. package/dist/cjs/schema/guard-lint.js +3 -12
  71. package/dist/cjs/schema/guards.js +38 -38
  72. package/dist/cjs/templates/asset-policy.js +190 -0
  73. package/dist/cjs/templates/index.js +86 -0
  74. package/dist/cjs/templates/machine.js +130 -0
  75. package/dist/cjs/templates/migration.js +39 -0
  76. package/dist/cjs/templates/state-shape.js +38 -0
  77. package/dist/cjs/validation.js +1 -3
  78. package/dist/esm/apps/compute/index.js +29 -0
  79. package/dist/esm/apps/compute/state-machines/compute-rule110.js +161 -0
  80. package/dist/esm/apps/compute/state-machines/index.js +5 -0
  81. package/dist/esm/apps/contracts/index.js +4 -4
  82. package/dist/esm/apps/contracts/state-machines/contract-agreement.js +128 -150
  83. package/dist/esm/apps/contracts/state-machines/contract-escrow.js +155 -176
  84. package/dist/esm/apps/contracts/state-machines/contract-universal.js +47 -59
  85. package/dist/esm/apps/corporate/index.js +2 -2
  86. package/dist/esm/apps/corporate/state-machines/corp-board.js +418 -484
  87. package/dist/esm/apps/corporate/state-machines/corp-entity.js +371 -443
  88. package/dist/esm/apps/corporate/state-machines/corp-securities.js +535 -650
  89. package/dist/esm/apps/corporate/state-machines/corp-shareholders.js +502 -606
  90. package/dist/esm/apps/governance/index.js +10 -10
  91. package/dist/esm/apps/governance/state-machines/dao-multisig.js +172 -211
  92. package/dist/esm/apps/governance/state-machines/dao-reputation.js +163 -216
  93. package/dist/esm/apps/governance/state-machines/dao-single.js +94 -94
  94. package/dist/esm/apps/governance/state-machines/dao-token.js +171 -225
  95. package/dist/esm/apps/governance/state-machines/governance-simple.js +187 -219
  96. package/dist/esm/apps/governance/state-machines/governance-universal.js +65 -65
  97. package/dist/esm/apps/identity/constants.js +18 -26
  98. package/dist/esm/apps/identity/index.js +8 -8
  99. package/dist/esm/apps/identity/state-machines/identity-agent.js +125 -159
  100. package/dist/esm/apps/identity/state-machines/identity-oracle.js +153 -171
  101. package/dist/esm/apps/identity/state-machines/identity-registry.js +91 -117
  102. package/dist/esm/apps/identity/state-machines/identity-universal.js +52 -58
  103. package/dist/esm/apps/index.js +9 -6
  104. package/dist/esm/apps/lending/assets.js +41 -17
  105. package/dist/esm/apps/lending/credit-scoring.js +6 -6
  106. package/dist/esm/apps/lending/eligibility.js +10 -26
  107. package/dist/esm/apps/lending/index.js +5 -5
  108. package/dist/esm/apps/lending/state-machines/lending-zk-loan.js +178 -157
  109. package/dist/esm/apps/markets/index.js +5 -5
  110. package/dist/esm/apps/markets/state-machines/market-auction.js +117 -136
  111. package/dist/esm/apps/markets/state-machines/market-crowdfund.js +124 -139
  112. package/dist/esm/apps/markets/state-machines/market-group-buy.js +160 -179
  113. package/dist/esm/apps/markets/state-machines/market-prediction.js +195 -229
  114. package/dist/esm/apps/markets/state-machines/market-universal.js +66 -81
  115. package/dist/esm/apps/oracles/index.js +3 -3
  116. package/dist/esm/apps/privacy/index.js +56 -0
  117. package/dist/esm/apps/privacy/state-machines/index.js +6 -0
  118. package/dist/esm/apps/privacy/state-machines/mixer-ddhRing.js +282 -0
  119. package/dist/esm/apps/privacy/state-machines/note-pool.js +470 -0
  120. package/dist/esm/apps/staked-pool/assets.js +91 -0
  121. package/dist/esm/apps/staked-pool/base.js +493 -0
  122. package/dist/esm/apps/staked-pool/consumer.js +49 -0
  123. package/dist/esm/apps/staked-pool/index.js +60 -0
  124. package/dist/esm/apps/staked-pool/state-machines/index.js +6 -0
  125. package/dist/esm/apps/staked-pool/state-machines/staked-pool-base.js +46 -0
  126. package/dist/esm/apps/staked-pool/state-machines/staked-pool-oracle.js +127 -0
  127. package/dist/esm/generated/google/protobuf/struct.js +1 -1
  128. package/dist/esm/generated/google/protobuf/timestamp.js +1 -1
  129. package/dist/esm/generated/ottochain/apps/contracts/v1/contract.js +1 -1
  130. package/dist/esm/generated/ottochain/apps/corporate/v1/corporate.js +1 -1
  131. package/dist/esm/generated/ottochain/apps/governance/v1/governance.js +1 -1
  132. package/dist/esm/generated/ottochain/apps/identity/v1/attestation.js +1 -1
  133. package/dist/esm/generated/ottochain/apps/identity/v1/identity.js +1 -1
  134. package/dist/esm/generated/ottochain/apps/markets/v1/market.js +1 -1
  135. package/dist/esm/generated/ottochain/v1/common.js +1 -1
  136. package/dist/esm/generated/ottochain/v1/fiber.js +40 -2
  137. package/dist/esm/generated/ottochain/v1/messages.js +1 -1
  138. package/dist/esm/generated/ottochain/v1/records.js +1 -1
  139. package/dist/esm/index.js +10 -4
  140. package/dist/esm/ottochain/genesis-manifest.js +6 -0
  141. package/dist/esm/ottochain/metagraph-client.js +63 -11
  142. package/dist/esm/ottochain/snapshot.js +2 -4
  143. package/dist/esm/ottochain/transaction.js +8 -0
  144. package/dist/esm/privacy/index.js +2 -2
  145. package/dist/esm/privacy/sealed-bid.js +87 -84
  146. package/dist/esm/privacy/shield-app.js +33 -33
  147. package/dist/esm/schema/effects.js +137 -0
  148. package/dist/esm/schema/fiber-app.js +134 -5
  149. package/dist/esm/schema/guard-lint.js +3 -12
  150. package/dist/esm/schema/guards.js +36 -37
  151. package/dist/esm/templates/asset-policy.js +182 -0
  152. package/dist/esm/templates/index.js +41 -0
  153. package/dist/esm/templates/machine.js +125 -0
  154. package/dist/esm/templates/migration.js +34 -0
  155. package/dist/esm/templates/state-shape.js +34 -0
  156. package/dist/esm/validation.js +1 -3
  157. package/dist/esm/zk/index.js +4 -4
  158. package/dist/types/apps/compute/index.d.ts +176 -0
  159. package/dist/types/apps/compute/state-machines/compute-rule110.d.ts +157 -0
  160. package/dist/types/apps/compute/state-machines/index.d.ts +5 -0
  161. package/dist/types/apps/contracts/index.d.ts +14 -14
  162. package/dist/types/apps/contracts/state-machines/contract-agreement.d.ts +3 -3
  163. package/dist/types/apps/contracts/state-machines/contract-escrow.d.ts +3 -3
  164. package/dist/types/apps/contracts/state-machines/contract-universal.d.ts +4 -4
  165. package/dist/types/apps/corporate/index.d.ts +162 -162
  166. package/dist/types/apps/corporate/state-machines/corp-board.d.ts +88 -88
  167. package/dist/types/apps/corporate/state-machines/corp-entity.d.ts +14 -14
  168. package/dist/types/apps/corporate/state-machines/corp-securities.d.ts +18 -18
  169. package/dist/types/apps/corporate/state-machines/corp-shareholders.d.ts +43 -43
  170. package/dist/types/apps/governance/index.d.ts +81 -81
  171. package/dist/types/apps/governance/state-machines/dao-multisig.d.ts +16 -16
  172. package/dist/types/apps/governance/state-machines/dao-reputation.d.ts +22 -22
  173. package/dist/types/apps/governance/state-machines/dao-token.d.ts +21 -21
  174. package/dist/types/apps/governance/state-machines/governance-simple.d.ts +11 -11
  175. package/dist/types/apps/governance/state-machines/governance-universal.d.ts +4 -4
  176. package/dist/types/apps/identity/constants.d.ts +2 -2
  177. package/dist/types/apps/identity/index.d.ts +70 -70
  178. package/dist/types/apps/identity/state-machines/identity-agent.d.ts +23 -23
  179. package/dist/types/apps/identity/state-machines/identity-oracle.d.ts +11 -11
  180. package/dist/types/apps/identity/state-machines/identity-registry.d.ts +27 -27
  181. package/dist/types/apps/identity/state-machines/identity-universal.d.ts +4 -4
  182. package/dist/types/apps/index.d.ts +9 -6
  183. package/dist/types/apps/lending/assets.d.ts +2 -2
  184. package/dist/types/apps/lending/credit-scoring.d.ts +5 -5
  185. package/dist/types/apps/lending/eligibility.d.ts +2 -2
  186. package/dist/types/apps/lending/index.d.ts +20 -12
  187. package/dist/types/apps/lending/state-machines/lending-zk-loan.d.ts +15 -7
  188. package/dist/types/apps/markets/index.d.ts +76 -76
  189. package/dist/types/apps/markets/state-machines/market-auction.d.ts +12 -12
  190. package/dist/types/apps/markets/state-machines/market-crowdfund.d.ts +19 -19
  191. package/dist/types/apps/markets/state-machines/market-group-buy.d.ts +18 -18
  192. package/dist/types/apps/markets/state-machines/market-prediction.d.ts +15 -15
  193. package/dist/types/apps/markets/state-machines/market-universal.d.ts +7 -7
  194. package/dist/types/apps/oracles/index.d.ts +1 -1
  195. package/dist/types/apps/privacy/index.d.ts +328 -0
  196. package/dist/types/apps/privacy/state-machines/index.d.ts +6 -0
  197. package/dist/types/apps/privacy/state-machines/mixer-ddhRing.d.ts +337 -0
  198. package/dist/types/apps/privacy/state-machines/note-pool.d.ts +196 -0
  199. package/dist/types/apps/staked-pool/assets.d.ts +53 -0
  200. package/dist/types/apps/staked-pool/base.d.ts +80 -0
  201. package/dist/types/apps/staked-pool/consumer.d.ts +29 -0
  202. package/dist/types/apps/staked-pool/index.d.ts +51 -0
  203. package/dist/types/apps/staked-pool/state-machines/index.d.ts +6 -0
  204. package/dist/types/apps/staked-pool/state-machines/staked-pool-base.d.ts +8 -0
  205. package/dist/types/apps/staked-pool/state-machines/staked-pool-oracle.d.ts +34 -0
  206. package/dist/types/generated/openapi.d.ts +13 -0
  207. package/dist/types/generated/ottochain/v1/fiber.d.ts +7 -0
  208. package/dist/types/index.d.ts +3 -3
  209. package/dist/types/openapi.d.ts +4 -2
  210. package/dist/types/ottochain/genesis-manifest.d.ts +6 -0
  211. package/dist/types/ottochain/index.d.ts +1 -1
  212. package/dist/types/ottochain/metagraph-client.d.ts +69 -15
  213. package/dist/types/ottochain/transaction.d.ts +9 -1
  214. package/dist/types/ottochain/types.d.ts +1 -1
  215. package/dist/types/privacy/index.d.ts +2 -2
  216. package/dist/types/privacy/sealed-bid.d.ts +9 -9
  217. package/dist/types/privacy/shield-app.d.ts +1 -1
  218. package/dist/types/schema/effects.d.ts +132 -0
  219. package/dist/types/schema/fiber-app.d.ts +281 -0
  220. package/dist/types/schema/guards.d.ts +12 -0
  221. package/dist/types/templates/asset-policy.d.ts +119 -0
  222. package/dist/types/templates/index.d.ts +26 -0
  223. package/dist/types/templates/machine.d.ts +139 -0
  224. package/dist/types/templates/migration.d.ts +34 -0
  225. package/dist/types/templates/state-shape.d.ts +30 -0
  226. package/dist/types/zk/index.d.ts +4 -4
  227. package/package.json +31 -13
@@ -105,6 +105,269 @@ export interface Transition<TState extends string = string, TEvent extends strin
105
105
  dependencies?: readonly (string | DependencySpec)[];
106
106
  emits?: readonly (string | EmitSpec)[];
107
107
  }
108
+ /**
109
+ * `allowedEffects` element — the 5 `EffectKind` families, UPPERCASE on the wire
110
+ * (`enumeratum` `Uppercase` mixin). Chain: `EffectKind` in `FiberPolicy.scala`.
111
+ */
112
+ export type EffectKind = 'TRIGGER' | 'SPAWN' | 'EMIT' | 'TRANSFER' | 'DEPENDENCY';
113
+ /**
114
+ * `spawnOwnerPolicy` — UPPERCASE (`enumeratum` `Uppercase`). Chain: `SpawnOwnerPolicy`
115
+ * (`Explicit` / `SubsetOfParent` / `InheritParent` ⇒ `"EXPLICIT"` / `"SUBSETOFPARENT"`
116
+ * / `"INHERITPARENT"`).
117
+ */
118
+ export type SpawnOwnerPolicy = 'EXPLICIT' | 'SUBSETOFPARENT' | 'INHERITPARENT';
119
+ /**
120
+ * `dependencyPolicy.mode` — UPPERCASE (`enumeratum` `Uppercase`). Chain: `DependencyMode`
121
+ * (`Open` / `Allowlist` / `Frozen`). REQUIRED on the wire (Scala defaults it to `Open`,
122
+ * but the `customizableEncoder` always encodes the value).
123
+ */
124
+ export type DependencyMode = 'OPEN' | 'ALLOWLIST' | 'FROZEN';
125
+ /**
126
+ * `transferPolicy` — recipient allowlist for `_transferAsset`. Chain: `TransferPolicy`
127
+ * (`Option[Set[UUID]]` fibers, `Option[Set[Address]]` wallets). Each field is OPTIONAL;
128
+ * an absent field ⇒ that recipient class is unconstrained (and is `dropNulls`-stripped).
129
+ */
130
+ export interface TransferPolicy {
131
+ /** Fiber UUIDs permitted to receive a transfer. */
132
+ allowedRecipientFibers?: readonly string[];
133
+ /** DAG wallet addresses permitted to receive a transfer. */
134
+ allowedRecipientWallets?: readonly string[];
135
+ }
136
+ /**
137
+ * `dependencyPolicy` — dynamic-dependency posture. Chain: `DependencyPolicy`
138
+ * (`mode: DependencyMode`, `allowed: Option[Set[UUID]]`). `mode` is REQUIRED; `allowed`
139
+ * is meaningful only when `mode === 'ALLOWLIST'` and is `dropNulls`-stripped otherwise.
140
+ */
141
+ export interface DependencyPolicy {
142
+ /** Posture: `OPEN` (any target) / `ALLOWLIST` (only `allowed`) / `FROZEN` (no new). */
143
+ mode: DependencyMode;
144
+ /** Fiber UUIDs permitted as dependency targets (meaningful only under `ALLOWLIST`). */
145
+ allowed?: readonly string[];
146
+ }
147
+ /**
148
+ * `migrationAuthority` — who may authorize a `Governed` migration. Chain:
149
+ * `MigrationAuthority`, a DISJOINT-FIELD discriminated union (no tag key): the `Signers`
150
+ * arm carries `addresses`, the `Role` arm carries `registryFiberId` + `roleField`. The
151
+ * presence of disjoint fields is the discriminator (same as the chain decoder's `.or`).
152
+ */
153
+ export type MigrationAuthority = {
154
+ /** VERIFIED signer DAG addresses permitted to authorize the migration (`Signers`). */
155
+ addresses: readonly string[];
156
+ } | {
157
+ /** Registry fiber UUID whose role-map is consulted (`Role`). */
158
+ registryFiberId: string;
159
+ /** Field/key in that fiber's state holding the `{<address>: true}` role map (`Role`). */
160
+ roleField: string;
161
+ };
162
+ /**
163
+ * `upgradePolicy` — the upgrade-path constitution. Chain: `UpgradePolicy`. The three
164
+ * bare variants encode as LOWERCASE tag STRINGS (`"immutable"` / `"appendOnly"` /
165
+ * `"arbitrary"`); the `Governed` arm encodes as the object `{ authority: <MigrationAuthority> }`.
166
+ *
167
+ * NOTE: this lowercase `"immutable"` is the upgradePolicy DIAL VALUE — distinct from the
168
+ * policy-level variant tag `"Immutable"` (capital-I), a different construct added in a
169
+ * later change.
170
+ */
171
+ export type UpgradePolicy = 'immutable' | 'appendOnly' | 'arbitrary' | {
172
+ /** Authority that may consent to a `Governed` migration. */
173
+ authority: MigrationAuthority;
174
+ };
175
+ /**
176
+ * `transitionPolicy` — WHO may drive a transition on this fiber. Chain: `TransitionPolicy`
177
+ * (chain PR #194), a bare tag STRING with three ranked levels:
178
+ *
179
+ * - `"Open"` — anyone may drive a transition; the transition's `guard` is the only gate.
180
+ * This is the chain DEFAULT when the dial is ABSENT, so omitting it is byte-identical
181
+ * to the legacy (pre-#194) behaviour.
182
+ * - `"OwnersOrParticipants"` — only the fiber's owners or its declared participants.
183
+ * - `"Owners"` — only the fiber's owners.
184
+ *
185
+ * Absent ⇒ `"Open"` (chain `transitionPolicy: Option[TransitionPolicy] = None`,
186
+ * `dropNulls`-stripped). The chain joins this to the tighten-only upgrade lattice, so an
187
+ * upgrade may only RAISE the level (`Open < OwnersOrParticipants < Owners`); LOOSENING it
188
+ * (including dropping the dial on a fiber that had it set) is rejected as `CombineRejected`.
189
+ */
190
+ export type TransitionPolicy = 'Open' | 'OwnersOrParticipants' | 'Owners';
191
+ /**
192
+ * `compatibleWith` — the inclusive-min / exclusive-max SemVer bridge window a migration
193
+ * may target. Chain: `VersionRange` (`min: Option[SemVer]`, `max: Option[SemVer]`). Each
194
+ * bound is a SemVer STRING (`"1.2.3"`); an absent bound is unconstrained on that side and
195
+ * is `dropNulls`-stripped.
196
+ */
197
+ export interface VersionRange {
198
+ /** Inclusive lower bound, e.g. `"1.0.0"` (absent ⇒ unconstrained below). */
199
+ min?: string;
200
+ /** Exclusive upper bound, e.g. `"2.0.0"` (absent ⇒ unconstrained above). */
201
+ max?: string;
202
+ }
203
+ /**
204
+ * `FiberPolicy` — the constitution a definition declares for the fibers it spawns.
205
+ *
206
+ * This MIRRORS the chain ADT `FiberPolicy = Unconstrained | Immutable | Constrained(<dials>)`
207
+ * (chain branch `feat/fiber-policy-adt`). The representation here is chosen for
208
+ * BYTE-FOR-BYTE wire parity with the chain, because a `StateMachineDefinition` is
209
+ * signed verbatim by the SDK (`batchSign(dropNulls(...))`) and re-encoded + verified
210
+ * by the chain. The rule is:
211
+ *
212
+ * - **`Unconstrained`** ⇒ there is **NO `policy` key** on the wire definition at all.
213
+ * In the SDK this is the DEFAULT and is represented by simply OMITTING `policy`
214
+ * (i.e. `policy === undefined`).
215
+ * - **`Immutable`** ⇒ the definition is permanently locked; `policy` is the bare JSON
216
+ * STRING `"Immutable"` (EXACT casing, capital-I) — NOT an object. Semantically this is
217
+ * the upgradePolicy DIAL set to its LOWERCASE `"immutable"` value with no other dial
218
+ * set, and the chain collapses that exact `Constrained` into the `Immutable` variant.
219
+ * See {@link immutable} and the canonical collapse in {@link projectFiberPolicy}.
220
+ * - **`Constrained(dials)`** ⇒ `policy` is a bare object of ONLY the dials that are
221
+ * SET. Unset dials are absent (the chain `dropNulls`-strips them; so does the SDK
222
+ * at sign time). A `Constrained` with no dials set is wire-indistinguishable from
223
+ * `Unconstrained`, so `toProtoDefinition` collapses it back to "no policy key".
224
+ *
225
+ * All 15 dials are optional. Provide any subset.
226
+ */
227
+ export interface FiberPolicyDials {
228
+ /** Whether the fiber may reproduce itself (spawn instances of its own definition). Wire: boolean. */
229
+ selfReproducing?: boolean;
230
+ /**
231
+ * Allow-list of effect families this fiber's transitions may produce, as a SET of the 5
232
+ * UPPERCASE {@link EffectKind} tokens (`"TRIGGER" | "SPAWN" | "EMIT" | "TRANSFER" |
233
+ * "DEPENDENCY"`). Order is not significant; duplicates are collapsed by the chain's `Set`.
234
+ * Chain: `allowedEffects: Option[Set[EffectKind]]`.
235
+ */
236
+ allowedEffects?: readonly EffectKind[];
237
+ /**
238
+ * Who/what may own fibers this one spawns — an UPPERCASE {@link SpawnOwnerPolicy} token
239
+ * (`"EXPLICIT" | "SUBSETOFPARENT" | "INHERITPARENT"`). Chain: `spawnOwnerPolicy: Option[SpawnOwnerPolicy]`.
240
+ */
241
+ spawnOwnerPolicy?: SpawnOwnerPolicy;
242
+ /** Maximum spawn-generation depth (descendant chain length). Wire: number. */
243
+ maxGenerations?: number;
244
+ /** Maximum number of children a single transition may spawn. Wire: number. */
245
+ maxSpawnFanout?: number;
246
+ /** SET of caller fiber UUIDs permitted to drive transitions on this fiber. Wire: string[]. */
247
+ acceptedCallers?: readonly string[];
248
+ /** SET of state ids that are sealed (no transition may fire from them). Wire: string[]. */
249
+ sealedStates?: readonly string[];
250
+ /**
251
+ * WHO may drive a transition on this fiber — a {@link TransitionPolicy} bare tag
252
+ * (`"Open" | "OwnersOrParticipants" | "Owners"`). Absent ⇒ `"Open"` (guard-only, the
253
+ * chain default); set `"Owners"`/`"OwnersOrParticipants"` to gate transitions by identity
254
+ * in ADDITION to the guard. Chain: `transitionPolicy: Option[TransitionPolicy]` (chain PR #194).
255
+ */
256
+ transitionPolicy?: TransitionPolicy;
257
+ /**
258
+ * Recipient allowlist for `_transferAsset` — the {@link TransferPolicy} object
259
+ * `{ allowedRecipientFibers?: uuid[], allowedRecipientWallets?: DAG-address[] }`.
260
+ * Chain: `transferPolicy: Option[TransferPolicy]`.
261
+ */
262
+ transferPolicy?: TransferPolicy;
263
+ /**
264
+ * Dynamic-dependency policy — the {@link DependencyPolicy} object `{ mode, allowed? }`
265
+ * where `mode` is the REQUIRED UPPERCASE {@link DependencyMode}. Chain:
266
+ * `dependencyPolicy: Option[DependencyPolicy]`.
267
+ */
268
+ dependencyPolicy?: DependencyPolicy;
269
+ /**
270
+ * In-place upgrade/migration posture — an {@link UpgradePolicy}: a LOWERCASE bare tag
271
+ * (`"immutable" | "appendOnly" | "arbitrary"`) OR the `Governed` object
272
+ * `{ authority: <MigrationAuthority> }`. Chain: `upgradePolicy: Option[UpgradePolicy]`.
273
+ */
274
+ upgradePolicy?: UpgradePolicy;
275
+ /** Self-declared SemVer of this definition as a STRING `"major.minor.patch"` (e.g. `"1.2.3"`). Chain: `version: Option[SemVer]`. */
276
+ version?: string;
277
+ /**
278
+ * Migration bridge window — the {@link VersionRange} object `{ min?: semver, max?: semver }`
279
+ * naming the successor versions this definition declares it will migrate TO. Chain:
280
+ * `compatibleWith: Option[VersionRange]`.
281
+ */
282
+ compatibleWith?: VersionRange;
283
+ /** SET of (ERC-165-style) interface identifiers this definition advertises. Wire: string[]. */
284
+ interfaces?: readonly string[];
285
+ /**
286
+ * Authority permitted to authorize a `Governed` migration — a {@link MigrationAuthority}:
287
+ * `{ addresses: DAG-address[] }` (Signers) OR `{ registryFiberId: uuid, roleField: string }`
288
+ * (Role), discriminated by disjoint fields. Chain: `migrationAuthority: Option[MigrationAuthority]`.
289
+ */
290
+ migrationAuthority?: MigrationAuthority;
291
+ }
292
+ /**
293
+ * The wire (and authoring) tag for the `Immutable` policy VARIANT: the bare JSON string
294
+ * `"Immutable"`. EXACT casing, capital-I — this is the POLICY-LEVEL variant name and is
295
+ * DISTINCT from the `upgradePolicy` dial VALUE `"immutable"` (lowercase). The chain emits
296
+ * exactly this capital-I string for `Immutable`, so the SDK must too, byte-for-byte.
297
+ */
298
+ export declare const IMMUTABLE_POLICY: "Immutable";
299
+ export type ImmutablePolicy = typeof IMMUTABLE_POLICY;
300
+ /**
301
+ * Wire form of a `FiberPolicy`. Mirrors the chain ADT's non-`Unconstrained` arms:
302
+ *
303
+ * - a bare object of the SET dials — the `Constrained` arm. Unset dials are stripped at
304
+ * projection time (and again by `dropNulls` at sign time), so this object matches the
305
+ * chain's `dropNulls`-stripped `Constrained` encoding exactly; OR
306
+ * - the bare JSON string `"Immutable"` — the {@link ImmutablePolicy} arm.
307
+ *
308
+ * (`Unconstrained` has no wire representation: it is the absence of the `policy` key.)
309
+ */
310
+ export type FiberPolicy = FiberPolicyDials | ImmutablePolicy;
311
+ /**
312
+ * The canonical UNCONSTRAINED policy: omission. Provided as a named export for
313
+ * readability at call sites — `policy: unconstrained()` documents intent, and projects
314
+ * to NO `policy` key (identical to leaving `policy` off entirely).
315
+ */
316
+ export declare function unconstrained(): undefined;
317
+ /**
318
+ * The canonical IMMUTABLE policy: the definition is permanently locked. Projects to the
319
+ * bare JSON string `"Immutable"` ({@link IMMUTABLE_POLICY}), the chain's `Immutable`
320
+ * variant tag. Semantically equivalent to `constrained({ upgradePolicy: 'immutable' })`
321
+ * with no other dial set — which `constrained()`/`projectFiberPolicy()` collapse to the
322
+ * same string for wire parity (see {@link constrained}).
323
+ *
324
+ * @example
325
+ * ```ts
326
+ * const def = defineFiberApp({ ...spec, policy: immutable() });
327
+ * ```
328
+ */
329
+ export declare function immutable(): ImmutablePolicy;
330
+ /**
331
+ * Build a CONSTRAINED `FiberPolicy` from any subset of the 15 dials.
332
+ *
333
+ * Pass only the dials you want to set. Dials left `undefined`/`null` are dropped so the
334
+ * result is a clean, minimal object that serializes identically to the chain's
335
+ * `dropNulls`-stripped `Constrained`. If NO dial is effectively set, this returns
336
+ * `undefined` (an empty constraint == `Unconstrained`), which projects to no `policy`
337
+ * key — preserving wire parity.
338
+ *
339
+ * CANONICAL COLLAPSE: `constrained({ upgradePolicy: 'immutable' })` with NO other dial set
340
+ * collapses to the bare string `"Immutable"` ({@link IMMUTABLE_POLICY}), because the chain
341
+ * collapses that exact `Constrained` into the `Immutable` variant. NOTE the casing: the
342
+ * collapse triggers on the chain's LOWERCASE upgradePolicy dial value `"immutable"`, and
343
+ * the result is the capital-I policy-variant tag `"Immutable"`. Signing the dials object
344
+ * `{ "upgradePolicy": "immutable" }` instead would diverge the canonical (the chain
345
+ * re-encodes it as `"Immutable"`) and break the create signature. Adding ANY other dial
346
+ * keeps it a dials object.
347
+ *
348
+ * @example
349
+ * ```ts
350
+ * const policy = constrained({
351
+ * selfReproducing: false,
352
+ * maxGenerations: 3,
353
+ * allowedEffects: ['EMIT', 'TRANSFER'],
354
+ * sealedStates: ['ARCHIVED'],
355
+ * });
356
+ * ```
357
+ */
358
+ export declare function constrained(dials: FiberPolicyDials): FiberPolicy | undefined;
359
+ /**
360
+ * Project an authoring `policy` value onto the wire form. Returns one of:
361
+ * - `undefined` when the policy is (effectively) `Unconstrained` — i.e. omit the `policy`
362
+ * key entirely;
363
+ * - the bare string `"Immutable"` ({@link IMMUTABLE_POLICY}) for the `Immutable` variant
364
+ * (also the collapse of a lone LOWERCASE `upgradePolicy: 'immutable'`); or
365
+ * - the minimal `Constrained` dials object otherwise.
366
+ *
367
+ * Centralizes the omit-on-unconstrained AND the Immutable-collapse parity rules so every
368
+ * projection path (`toProtoDefinition`, the genesis manifest) stays consistent.
369
+ */
370
+ export declare function projectFiberPolicy(policy: FiberPolicy | undefined): FiberPolicy | undefined;
108
371
  export interface FiberAppMetadata {
109
372
  name: string;
110
373
  app: string;
@@ -125,6 +388,16 @@ export interface CrossReferences {
125
388
  }
126
389
  export interface FiberAppDefinition<TState extends string = string, TEvent extends string = string> {
127
390
  metadata: FiberAppMetadata;
391
+ /**
392
+ * Fiber constitution. Mirrors the chain ADT `FiberPolicy = Unconstrained | Immutable |
393
+ * Constrained(<dials>)`. OMIT this field (the default) for `Unconstrained` — the projected
394
+ * wire definition then has NO `policy` key. Set it to `immutable()` to permanently lock the
395
+ * definition (projects to the bare string `"Immutable"`). Set it to a `constrained({...})`
396
+ * object to declare a subset of the 15 dials; unset dials are stripped so the wire form
397
+ * matches the chain's `dropNulls`-stripped `Constrained` byte-for-byte (and a lone
398
+ * `upgradePolicy: 'immutable'` collapses to `"Immutable"`).
399
+ */
400
+ policy?: FiberPolicy;
128
401
  /** Schema for fiber creation inputs (user-provided) */
129
402
  createSchema?: {
130
403
  required?: readonly string[];
@@ -195,6 +468,14 @@ export interface ProtoStateMachineDefinition {
195
468
  dependencies: string[];
196
469
  }>;
197
470
  metadata?: Record<string, unknown>;
471
+ /**
472
+ * Fiber constitution. PRESENT for `Constrained` (a bare object of the SET dials) and for
473
+ * `Immutable` (the bare string `"Immutable"`); ABSENT for `Unconstrained`. This
474
+ * omit-on-unconstrained rule is the wire parity contract: the chain emits no `policy` key
475
+ * for `Unconstrained`, so neither may the SDK, or the signature breaks (HTTP 400). See
476
+ * {@link projectFiberPolicy}.
477
+ */
478
+ policy?: FiberPolicy;
198
479
  }
199
480
  /**
200
481
  * Extract proto-compatible StateMachineDefinition from a FiberAppDefinition.
@@ -131,4 +131,16 @@ export declare const signerHasRoleVia: (registryIdVar: string, roleField: string
131
131
  * so a single gated transition is split into a bind step then this assert step. See
132
132
  * docs/design/app-hardening-identity-integration.md §5–§6.
133
133
  */
134
+ /**
135
+ * EFFECT-KEY-BINDING dedup over an ARRAY of records: no existing element of the array at `arrayVar`
136
+ * (e.g. `"state.submissions"`, shaped `[ { addr, value }, … ]`) has its `field` (default `"addr"`)
137
+ * equal to the actor at `actorVar` (default `"event.agent"`). The array analog of the map-keyed
138
+ * `{"!":[has(...)]}` dedup — used where the collection is an append-only array of `{addr,…}` records
139
+ * (there is no `(array,string)` key check, but `none` over the array with a per-element `===` is total).
140
+ *
141
+ * The bare-element callback context inside `none` sees each record map directly, so `{get:[{var:""},field]}`
142
+ * is a valid `(map,string)` read. Pair with an `actorIsSigner`/`actorHasEntry` clause on the same
143
+ * `actorVar` (the dedup proves "not yet present", not "is the verified signer").
144
+ */
145
+ export declare const actorNotInArray: (arrayVar: string, field?: string, actorVar?: string) => GuardRule;
134
146
  export declare const depInState: (refVar: string, requiredState: string) => GuardRule;
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Asset-policy preset builders (§1.1 of the SDK std-lib/templates handoff).
3
+ *
4
+ * Each builder is a PURE function that emits the exact {@link CreateAssetPolicy} wire body the chain
5
+ * re-derives — no `Date.now()`/`Math.random()`/`crypto.randomUUID()`; fixed inputs → fixed output. The
6
+ * on-chain policy `schemaHash` and `logicHash` are both `RegistryShape.AssetPolicy.computeDigest` over
7
+ * `behavior`/`supply`/`morphisms`/`stateShape` (no JSON-Logic body), so these presets are pure data.
8
+ *
9
+ * Hard invariants (CLAUDE.md rule #1 — the signed canonical is frozen):
10
+ * - `behavior` is ALWAYS summed from {@link TOKEN_BEHAVIOR_BITS} (T=16, S=8, C=4, E=2, G=1), never a
11
+ * magic literal int.
12
+ * - `morphisms` is REQUIRED on the wire (presence required, emptiness meaningful) — emit `{}` when empty,
13
+ * NEVER omit it.
14
+ * - `supply` is REQUIRED — emit `{}` when there is no supply authority, never omit it.
15
+ * - Absent optionals are OMITTED, never emitted as `null`/`undefined` (the chain signs over
16
+ * `JCS(dropNulls(payload))`).
17
+ *
18
+ * @see src/ottochain/types.ts — CreateAssetPolicy, SupplyPolicy, MorphismSpec, MorphismKind, TOKEN_BEHAVIOR_BITS
19
+ */
20
+ import { TOKEN_BEHAVIOR_BITS, type CreateAssetPolicy, type JsonLogicExpression, type MorphismKind, type MorphismSpec, type SupplyPolicy } from '../ottochain/types.js';
21
+ /** A behavior-bit NAME (a key of {@link TOKEN_BEHAVIOR_BITS}) — the only legal way to spell `behavior`. */
22
+ export type BehaviorBitName = keyof typeof TOKEN_BEHAVIOR_BITS;
23
+ /** Sum behavior bits from their NAMES — never a magic literal int (CLAUDE.md #1). */
24
+ export declare function sumBehavior(bits: readonly BehaviorBitName[]): number;
25
+ /**
26
+ * Derive the default `stateShape.typeName`: strip a trailing `.asset` label, PascalCase the remainder
27
+ * (splitting on `.`/`-`/`_`/space), then append `State`.
28
+ * `rvd.asset` → `RvdState`, `goods.asset` → `GoodsState`, `capped.asset` → `CappedState`.
29
+ */
30
+ export declare function defaultStateTypeName(name: string): string;
31
+ /**
32
+ * Fungible currency. Behavior `T|S|C = 28` (transferable + splittable + combinable). Standard morphism
33
+ * set TRANSFER + FRACTIONALIZE + STAKE (`stakeable`, default true) + BURN (when `burnable`), all PUBLIC.
34
+ *
35
+ * Reproduces `riverdale-economy/rvd-policy.json` exactly via
36
+ * `fungiblePolicy({ name: 'rvd.asset', version: '1.0.0', mintable: true, burnable: true })`.
37
+ */
38
+ export declare function fungiblePolicy(p: {
39
+ /** Registry name; conventionally ends `.asset`. */
40
+ name: string;
41
+ /** SemVer string. */
42
+ version: string;
43
+ /** `supply.decimals` — fractional precision; omit for whole-unit. */
44
+ decimals?: number;
45
+ /** `supply.maxSupply` — omit ⇒ uncapped. */
46
+ maxSupply?: number;
47
+ /** true ⇒ `supply.mintPolicy = {"==":[1,1]}` (open mint). */
48
+ mintable?: boolean;
49
+ /** true ⇒ `supply.burnPolicy = {"==":[1,1]}` AND a BURN morphism. */
50
+ burnable?: boolean;
51
+ /** JSON-Logic predicate that OVERRIDES `mintable`'s default mint guard (and enables minting). */
52
+ mintGuard?: JsonLogicExpression;
53
+ /** default true ⇒ a STAKE morphism. */
54
+ stakeable?: boolean;
55
+ /** `stateShape.typeName`; default `${PascalCase(name-without-.asset)}State`. */
56
+ stateTypeName?: string;
57
+ /** Off-chain links grab-bag; omitted when absent. */
58
+ metadata?: Record<string, string>;
59
+ }): CreateAssetPolicy;
60
+ /**
61
+ * Non-fungible token. Behavior `T = 16`, or `T|C = 20` with `combinable: true` (the riverdale
62
+ * `goods.asset`); `transferable: false` drops the T bit (a bound collectible). `morphisms` is `{}` by
63
+ * default (emitted explicitly, never omitted). Mintable by default ⇒ `supply.mintPolicy = {"==":[1,1]}`.
64
+ *
65
+ * Reproduces `riverdale-economy/goods-policy.json` exactly via
66
+ * `nftPolicy({ name: 'goods.asset', version: '1.0.0', combinable: true })`.
67
+ */
68
+ export declare function nftPolicy(p: {
69
+ name: string;
70
+ version: string;
71
+ /** `T(16)` → `T|C(20)`. */
72
+ combinable?: boolean;
73
+ /** default true; false ⇒ drop the T bit (bound collectible: `0`, or `4` with `combinable`). */
74
+ transferable?: boolean;
75
+ /** default true ⇒ `supply.mintPolicy = {"==":[1,1]}`. */
76
+ mintable?: boolean;
77
+ /** JSON-Logic predicate that OVERRIDES the default mint guard. */
78
+ mintGuard?: JsonLogicExpression;
79
+ /** `supply.maxSupply` — omit ⇒ uncapped edition. */
80
+ maxSupply?: number;
81
+ /** `stateShape.typeName`; default `${PascalCase(name-without-.asset)}State`. */
82
+ stateTypeName?: string;
83
+ metadata?: Record<string, string>;
84
+ }): CreateAssetPolicy;
85
+ /**
86
+ * Soulbound token: non-transferable, governable only (`G = 1`; `+E = 3` when `expirable`). No TRANSFER
87
+ * morphism (`morphisms: {}`); minting is closed after issue (empty `supply`).
88
+ */
89
+ export declare function soulboundPolicy(p: {
90
+ name: string;
91
+ version: string;
92
+ /** `+E(2)` ⇒ behavior `3`. */
93
+ expirable?: boolean;
94
+ /** `stateShape.typeName`; default `${PascalCase(name-without-.asset)}State`. */
95
+ stateTypeName?: string;
96
+ metadata?: Record<string, string>;
97
+ }): CreateAssetPolicy;
98
+ /**
99
+ * Escape hatch: declare `behavior` by NAME (summed from {@link TOKEN_BEHAVIOR_BITS}, never a magic int)
100
+ * and pass `supply` + `morphisms` through raw. Use when no preset fits.
101
+ *
102
+ * Reproduces `riverdale-economy/capped-policy.json` exactly via
103
+ * `customPolicy({ name: 'capped.asset', version: '1.0.0',
104
+ * behavior: ['transferable', 'splittable', 'combinable'],
105
+ * supply: { maxSupply: 100, mintPolicy: { '==': [1, 1] } }, morphisms: {} })`.
106
+ */
107
+ export declare function customPolicy(p: {
108
+ name: string;
109
+ version: string;
110
+ /** Behavior-bit NAMES summed to the int (e.g. `['transferable','combinable']` ⇒ 20). Never a literal. */
111
+ behavior: readonly BehaviorBitName[];
112
+ /** Raw supply authority, passed through verbatim. */
113
+ supply: SupplyPolicy;
114
+ /** Raw morphism map, passed through verbatim (emit `{}` when empty, never omit). */
115
+ morphisms: Partial<Record<MorphismKind, MorphismSpec>>;
116
+ /** `stateShape.typeName`; default `${PascalCase(name-without-.asset)}State`. */
117
+ stateTypeName?: string;
118
+ metadata?: Record<string, string>;
119
+ }): CreateAssetPolicy;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `@ottochain/sdk/templates` — the fiber & asset authoring template catalog.
3
+ *
4
+ * Typed builders that emit the EXACT canonical wire shapes app authors otherwise hand-roll as raw
5
+ * JSON-Logic (asset policies, versioned machines, effect directives, migrations, seeded state). Every
6
+ * builder is additive and pure — it returns the same wire shape the chain re-derives, so a template
7
+ * output signs to byte-identical `JCS(dropNulls(payload))` (CLAUDE.md rule #1). Hand-rolled JSON keeps
8
+ * working; these just make the recurring shapes typed, named, and mistake-resistant.
9
+ *
10
+ * Origin: the fiber-ergonomics program (ottochain `docs/proposals/fiber-ergonomics/`), Phase A — the
11
+ * `riverdale-economy` e2e is the migration proof (each preset reproduces its checked-in golden JSON).
12
+ *
13
+ * @example
14
+ * import {
15
+ * fungiblePolicy, machine, transition, effect, guard,
16
+ * transferAsset, triggers, spawn, seedState, seedFields,
17
+ * } from '@ottochain/sdk/templates';
18
+ */
19
+ export * from './asset-policy.js';
20
+ export * from './machine.js';
21
+ export * from './migration.js';
22
+ export * from './state-shape.js';
23
+ export * from '../schema/effects.js';
24
+ export * as guard from '../schema/guards.js';
25
+ export { defineFiberApp, toProtoDefinition, constrained, unconstrained, immutable, projectFiberPolicy, } from '../schema/fiber-app.js';
26
+ export type { FiberAppDefinition, Transition, ProtoStateMachineDefinition, FiberPolicy, FiberPolicyDials, } from '../schema/fiber-app.js';
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Versioned-machine skeleton + `transition()` / `effect()` composition (handoff §1.2).
3
+ *
4
+ * Two moves:
5
+ * 1. `transition()` / `effect()` build the wire `Transition` + its flat effect map from typed
6
+ * fragments instead of a hand-rolled JSON blob.
7
+ * 2. `machine()` is a versioned-package SKELETON that OWNS exactly ONE canonical wire definition
8
+ * (`toProtoDefinition(app)`, computed once) and hands the SAME object to BOTH `publishVersion()`
9
+ * and `create()`. That is the verified-binding invariant (F9): because publish and create cannot
10
+ * drift, the chain's `definition.computeDigest` equals the registered `logicHash` and the bind
11
+ * admits the fiber. The skeleton REUSES `toProtoDefinition` (the one canonicalization path) — it
12
+ * never re-derives the wire shape.
13
+ *
14
+ * Guardrail (CLAUDE.md #1): every builder here is a pure function emitting the exact wire shape the
15
+ * chain re-derives. Absent optionals (`metadata`/`participants`/`parentFiberId`/`migration`) are
16
+ * OMITTED, never `null`; required-no-default fields (`strict` on publish, `dependencies: []` per
17
+ * transition) are ALWAYS present.
18
+ */
19
+ import { type Transition, type JsonLogicRule, type DependencySpec, type FiberAppDefinition, type ProtoStateMachineDefinition } from '../schema/fiber-app.js';
20
+ import type { MachineShape, PublishMachineVersion, CreateStateMachine, UpgradeFiber, SemVer, JsonLogicValue, JsonLogicExpression } from '../ottochain/types.js';
21
+ /** Authoring shape for {@link transition} — `on` is the event name (mapped to the wire `eventName`). */
22
+ export interface TransitionSpec<TState extends string = string, TEvent extends string = string> {
23
+ from: TState;
24
+ to: TState;
25
+ /** Event that fires this transition. Mapped to the wire key `eventName`. */
26
+ on: TEvent;
27
+ /** JSON-Logic predicate; defaults to the always-true `{ "==": [1, 1] }` when omitted. */
28
+ guard?: JsonLogicRule;
29
+ /** The flat effect map (build it with {@link effect}). Passed through verbatim. */
30
+ effect?: JsonLogicRule;
31
+ /**
32
+ * Dependencies for this transition. Defaults to `[]` (ALWAYS present — the chain
33
+ * `Transition.dependencies: Set[UUID]` has no default; omitting it diverges the canonical).
34
+ * `toProtoDefinition` later drops any non-string {@link DependencySpec} authoring entries.
35
+ */
36
+ dependencies?: readonly (string | DependencySpec)[];
37
+ }
38
+ /**
39
+ * Build a wire {@link Transition} from a typed spec.
40
+ *
41
+ * - `on` → `eventName` (the wire key);
42
+ * - `guard` defaults to `{ "==": [1, 1] }`;
43
+ * - `dependencies` defaults to `[]` and is ALWAYS present;
44
+ * - `effect` is passed through (build it with {@link effect}).
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * transition({
49
+ * from: 'debt_current', to: 'debt_current', on: 'buy',
50
+ * effect: effect(
51
+ * { status: 'debt_current', purchaseCount: { '+': [{ var: 'state.purchaseCount' }, 1] } },
52
+ * triggers([...]), transferAsset([...]),
53
+ * ),
54
+ * });
55
+ * ```
56
+ */
57
+ export declare function transition<TState extends string = string, TEvent extends string = string>(t: TransitionSpec<TState, TEvent>): Transition<TState, TEvent>;
58
+ /**
59
+ * Compose an effect into ONE FLAT map: the state-update fields PLUS any `_`-directive fragments,
60
+ * all in a single object (`Object.assign({}, stateUpdate, ...directives)`).
61
+ *
62
+ * Riverdale effects are flat maps that mix `_`-reserved directives (`_triggers`, `_transferAsset`,
63
+ * `_spawn`, …) with plain state-update fields — they are NOT `merge`-wrapped. Each directive fragment
64
+ * is a `Record` (e.g. the output of `transferAsset(...)` / `triggers(...)`), spread in here. Later
65
+ * fragments override earlier keys (`Object.assign` semantics).
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * effect(
70
+ * { status: 'debt_current', purchaseCount: { '+': [{ var: 'state.purchaseCount' }, 1] } },
71
+ * { _triggers: [...] },
72
+ * transferAsset([{ assetId: { var: 'event.payAssetId' }, recipient: toFiber({ var: 'event.retailerId' }) }]),
73
+ * );
74
+ * // => { status, purchaseCount, _triggers, _transferAsset }
75
+ * ```
76
+ */
77
+ export declare function effect(stateUpdate: Record<string, unknown>, ...directives: Record<string, unknown>[]): Record<string, unknown>;
78
+ /** The machine package spec: identity (`name`@`version`) + the one canonical `app` + its schema shape. */
79
+ export interface MachineSpec<TState extends string = string, TEvent extends string = string> {
80
+ /** Full registry name `labels.tld` (e.g. `"consumer.package"`). */
81
+ name: string;
82
+ /** SemVer string (e.g. `"1.0.0"`). */
83
+ version: SemVer;
84
+ /** The typed fiber app; projected ONCE to the canonical wire definition via `toProtoDefinition`. */
85
+ app: FiberAppDefinition<TState, TEvent>;
86
+ /** The advisory proto projection the chain stores for discovery (carried onto `PublishMachineVersion.machineShape`). */
87
+ schemaShape: MachineShape;
88
+ }
89
+ /** Options for {@link Machine.publishVersion}. */
90
+ export interface PublishVersionOptions {
91
+ /** Opt-in runtime conformance gate (#33). Defaults to `false` (REQUIRED on the wire — never omitted). */
92
+ strict?: boolean;
93
+ /** Optional off-chain links grab-bag; OMITTED when absent (never `null`). */
94
+ metadata?: Record<string, string>;
95
+ /**
96
+ * Base64 of the proto FileDescriptorSet. REQUIRED on the wire `PublishMachineVersion` (the chain
97
+ * base64-validates + hashes it, then drops the bytes), so it is ALWAYS present; defaults to the empty
98
+ * string `''` (valid empty base64) when the skeleton has no descriptor set bound. The verified binding
99
+ * hangs on `definition.computeDigest`, NOT on this field.
100
+ */
101
+ schemaB64?: string;
102
+ }
103
+ /** Options for {@link Machine.create}. */
104
+ export interface CreateOptions {
105
+ fiberId: string;
106
+ /** Seeded fiber state (e.g. from `seedState(...)`); pre-seed accumulators so no field reads `null`. */
107
+ initialData: JsonLogicValue;
108
+ /** Optional DAG addresses authorized to sign transitions; OMITTED when absent (never `null`). */
109
+ participants?: string[];
110
+ /** Optional parent fiber UUID; OMITTED when absent (never `null`). */
111
+ parentFiberId?: string;
112
+ }
113
+ /** Options for {@link Machine.upgradeFrom}. */
114
+ export interface UpgradeOptions {
115
+ fiberId: string;
116
+ targetSequenceNumber: number;
117
+ /** Optional JSON-Logic migration transform of the prior state; OMITTED when absent (never `null`). */
118
+ migration?: JsonLogicExpression;
119
+ }
120
+ /** The versioned-machine skeleton returned by {@link machine}. */
121
+ export interface Machine {
122
+ /** The ONE canonical wire definition (`toProtoDefinition(app)`), shared by publish + create. */
123
+ wireDefinition(): ProtoStateMachineDefinition;
124
+ /** The `PublishMachineVersion` body — its `definition` is the SAME object as `wireDefinition()`. */
125
+ publishVersion(o?: PublishVersionOptions): PublishMachineVersion;
126
+ /** The `CreateStateMachine` body — references `name@version` via `schemaRef` + the SAME `definition`. */
127
+ create(o: CreateOptions): CreateStateMachine;
128
+ /** The `UpgradeFiber` body — re-pins to `name@version` with the SAME `newDefinition`. */
129
+ upgradeFrom(o: UpgradeOptions): UpgradeFiber;
130
+ }
131
+ /**
132
+ * Build a versioned-machine skeleton that binds publish + create to ONE canonical definition.
133
+ *
134
+ * The definition is projected ONCE here (`toProtoDefinition(spec.app)`) and the SAME reference is handed
135
+ * to `wireDefinition()`, `publishVersion().definition`, `create().definition`, and
136
+ * `upgradeFrom().newDefinition` — so they cannot drift and the chain's verified binding admits the fiber
137
+ * (F9). REUSES `toProtoDefinition` (the single canonicalization path); never re-derives the wire shape.
138
+ */
139
+ export declare function machine<TState extends string = string, TEvent extends string = string>(spec: MachineSpec<TState, TEvent>): Machine;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Migration builders — the `UpgradeFiber.migration` JSON-Logic transform applied on a version upgrade.
3
+ *
4
+ * THE FOOT-GUN (F9): a migration's evaluation root is the BARE prior state, not `state.x`.
5
+ * The chain evaluates the migration expression against `sm.stateData` directly
6
+ * (`MeteredEvaluator.eval(expr, sm.stateData, Migration)`, FiberEngine.scala:300), so:
7
+ * - `{ var: '' }` => the WHOLE prior state object
8
+ * - `{ var: 'loyaltyPoints' }` => the top-level `loyaltyPoints` field
9
+ * This is UNLIKE an effect, where the root is the transition context and you read `{ var: 'state.x' }`.
10
+ * Writing `state.loyaltyPoints` in a migration silently reads `undefined`. These helpers hide that
11
+ * asymmetry by pinning the bare-state root for you.
12
+ *
13
+ * `migration` is `Option` on `UpgradeFiber` — when there is no transform, OMIT the key (never send `null`).
14
+ */
15
+ /**
16
+ * Seed / overwrite top-level state fields on a version upgrade.
17
+ * Emits `{ merge: [{ var: '' }, fields] }` — merges `fields` onto the bare prior state, so existing
18
+ * fields are preserved and the named fields are added or overwritten.
19
+ *
20
+ * The `{ var: '' }` root is the BARE prior state (NOT `state.x` like an effect) — that asymmetry is
21
+ * exactly the F9 foot-gun this helper hides.
22
+ *
23
+ * @example seedFields({ loyaltyPoints: 0 }) // => { merge: [{ var: '' }, { loyaltyPoints: 0 }] }
24
+ */
25
+ export declare const seedFields: (fields: Record<string, unknown>) => unknown;
26
+ /**
27
+ * General migration transform with the bare-state root made explicit. `build` receives `{ var: '' }`
28
+ * (the whole prior state) and returns the migration JSON-Logic.
29
+ *
30
+ * @example migration((s) => ({ merge: [s, { x: 1 }] })) // => { merge: [{ var: '' }, { x: 1 }] }
31
+ */
32
+ export declare const migration: (build: (priorState: {
33
+ var: "";
34
+ }) => unknown) => unknown;