@ottochain/sdk 2.3.0 → 2.5.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 (287) 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 +16 -9
  5. package/dist/cjs/apps/contracts/state-machines/contract-agreement.js +134 -161
  6. package/dist/cjs/apps/contracts/state-machines/contract-escrow.js +192 -170
  7. package/dist/cjs/apps/contracts/state-machines/contract-universal.js +46 -58
  8. package/dist/cjs/apps/corporate/index.js +2 -2
  9. package/dist/cjs/apps/corporate/state-machines/corp-board.js +500 -456
  10. package/dist/cjs/apps/corporate/state-machines/corp-entity.js +487 -361
  11. package/dist/cjs/apps/corporate/state-machines/corp-securities.js +769 -576
  12. package/dist/cjs/apps/corporate/state-machines/corp-shareholders.js +567 -557
  13. package/dist/cjs/apps/governance/index.js +21 -21
  14. package/dist/cjs/apps/governance/state-machines/dao-multisig.js +188 -209
  15. package/dist/cjs/apps/governance/state-machines/dao-reputation.js +181 -228
  16. package/dist/cjs/apps/governance/state-machines/dao-single.js +105 -88
  17. package/dist/cjs/apps/governance/state-machines/dao-token.js +199 -227
  18. package/dist/cjs/apps/governance/state-machines/governance-simple.js +231 -231
  19. package/dist/cjs/apps/governance/state-machines/governance-universal.js +64 -64
  20. package/dist/cjs/apps/identity/constants.js +55 -22
  21. package/dist/cjs/apps/identity/index.js +28 -12
  22. package/dist/cjs/apps/identity/state-machines/identity-agent.js +124 -158
  23. package/dist/cjs/apps/identity/state-machines/identity-oracle.js +158 -173
  24. package/dist/cjs/apps/identity/state-machines/identity-registry.js +262 -0
  25. package/dist/cjs/apps/identity/state-machines/identity-universal.js +51 -57
  26. package/dist/cjs/apps/identity/state-machines/index.js +3 -1
  27. package/dist/cjs/apps/index.js +22 -8
  28. package/dist/cjs/apps/lending/assets.js +247 -0
  29. package/dist/cjs/apps/lending/credit-scoring.js +87 -0
  30. package/dist/cjs/apps/lending/eligibility.js +105 -0
  31. package/dist/cjs/apps/lending/index.js +91 -0
  32. package/dist/cjs/apps/lending/state-machines/index.js +9 -0
  33. package/dist/cjs/apps/lending/state-machines/lending-zk-loan.js +433 -0
  34. package/dist/cjs/apps/markets/index.js +22 -12
  35. package/dist/cjs/apps/markets/state-machines/market-auction.js +116 -134
  36. package/dist/cjs/apps/markets/state-machines/market-crowdfund.js +131 -141
  37. package/dist/cjs/apps/markets/state-machines/market-group-buy.js +163 -184
  38. package/dist/cjs/apps/markets/state-machines/market-prediction.js +226 -233
  39. package/dist/cjs/apps/markets/state-machines/market-universal.js +65 -80
  40. package/dist/cjs/apps/oracles/index.js +3 -3
  41. package/dist/cjs/apps/privacy/index.js +67 -0
  42. package/dist/cjs/apps/privacy/state-machines/index.js +17 -0
  43. package/dist/cjs/apps/privacy/state-machines/mixer-ddhRing.js +286 -0
  44. package/dist/cjs/apps/privacy/state-machines/note-pool.js +476 -0
  45. package/dist/cjs/apps/staked-pool/assets.js +103 -0
  46. package/dist/cjs/apps/staked-pool/base.js +498 -0
  47. package/dist/cjs/apps/staked-pool/consumer.js +55 -0
  48. package/dist/cjs/apps/staked-pool/index.js +83 -0
  49. package/dist/cjs/apps/staked-pool/state-machines/index.js +12 -0
  50. package/dist/cjs/apps/staked-pool/state-machines/staked-pool-base.js +49 -0
  51. package/dist/cjs/apps/staked-pool/state-machines/staked-pool-oracle.js +131 -0
  52. package/dist/cjs/errors.js +3 -3
  53. package/dist/cjs/generated/google/protobuf/struct.js +5 -5
  54. package/dist/cjs/generated/google/protobuf/timestamp.js +1 -1
  55. package/dist/cjs/generated/index.js +11 -7
  56. package/dist/cjs/generated/openapi.js +6 -0
  57. package/dist/cjs/generated/ottochain/apps/contracts/v1/contract.js +51 -51
  58. package/dist/cjs/generated/ottochain/apps/corporate/v1/corporate.js +20 -21
  59. package/dist/cjs/generated/ottochain/apps/governance/v1/governance.js +14 -14
  60. package/dist/cjs/generated/ottochain/apps/identity/v1/attestation.js +5 -5
  61. package/dist/cjs/generated/ottochain/apps/identity/v1/identity.js +125 -131
  62. package/dist/cjs/generated/ottochain/apps/markets/v1/market.js +108 -108
  63. package/dist/cjs/generated/ottochain/v1/common.js +5 -5
  64. package/dist/cjs/generated/ottochain/v1/fiber.js +44 -6
  65. package/dist/cjs/generated/ottochain/v1/messages.js +1 -1
  66. package/dist/cjs/generated/ottochain/v1/records.js +1 -1
  67. package/dist/cjs/index.js +58 -7
  68. package/dist/cjs/openapi.js +2 -0
  69. package/dist/cjs/ottochain/drop-nulls.js +1 -2
  70. package/dist/cjs/ottochain/genesis-manifest.js +17 -11
  71. package/dist/cjs/ottochain/index.js +23 -13
  72. package/dist/cjs/ottochain/metagraph-client.js +81 -16
  73. package/dist/cjs/ottochain/snapshot.js +13 -16
  74. package/dist/cjs/ottochain/transaction.js +67 -14
  75. package/dist/cjs/ottochain/types.js +16 -2
  76. package/dist/cjs/privacy/index.js +14 -0
  77. package/dist/cjs/privacy/sealed-bid.js +213 -0
  78. package/dist/cjs/privacy/shield-app.js +131 -0
  79. package/dist/cjs/schema/effects.js +156 -0
  80. package/dist/cjs/schema/fiber-app.js +150 -15
  81. package/dist/cjs/schema/guard-lint.js +343 -0
  82. package/dist/cjs/schema/guards.js +246 -0
  83. package/dist/cjs/signing.js +80 -0
  84. package/dist/cjs/templates/asset-policy.js +190 -0
  85. package/dist/cjs/templates/index.js +86 -0
  86. package/dist/cjs/templates/machine.js +130 -0
  87. package/dist/cjs/templates/migration.js +39 -0
  88. package/dist/cjs/templates/state-shape.js +38 -0
  89. package/dist/cjs/types.js +2 -3
  90. package/dist/cjs/validation.js +9 -11
  91. package/dist/cjs/verify.js +9 -4
  92. package/dist/cjs/zk/commit.js +53 -0
  93. package/dist/cjs/zk/guard.js +107 -0
  94. package/dist/cjs/zk/index.js +48 -0
  95. package/dist/cjs/zk/preimage.js +37 -0
  96. package/dist/cjs/zk/prover.js +87 -0
  97. package/dist/cjs/zk/registry.js +62 -0
  98. package/dist/cjs/zk/types.js +28 -0
  99. package/dist/cjs/zk/witness.js +19 -0
  100. package/dist/esm/apps/compute/index.js +29 -0
  101. package/dist/esm/apps/compute/state-machines/compute-rule110.js +161 -0
  102. package/dist/esm/apps/compute/state-machines/index.js +5 -0
  103. package/dist/esm/apps/contracts/index.js +9 -5
  104. package/dist/esm/apps/contracts/state-machines/contract-agreement.js +135 -162
  105. package/dist/esm/apps/contracts/state-machines/contract-escrow.js +193 -171
  106. package/dist/esm/apps/contracts/state-machines/contract-universal.js +47 -59
  107. package/dist/esm/apps/corporate/index.js +2 -2
  108. package/dist/esm/apps/corporate/state-machines/corp-board.js +501 -457
  109. package/dist/esm/apps/corporate/state-machines/corp-entity.js +488 -362
  110. package/dist/esm/apps/corporate/state-machines/corp-securities.js +770 -577
  111. package/dist/esm/apps/corporate/state-machines/corp-shareholders.js +568 -558
  112. package/dist/esm/apps/governance/index.js +10 -10
  113. package/dist/esm/apps/governance/state-machines/dao-multisig.js +189 -210
  114. package/dist/esm/apps/governance/state-machines/dao-reputation.js +182 -229
  115. package/dist/esm/apps/governance/state-machines/dao-single.js +106 -89
  116. package/dist/esm/apps/governance/state-machines/dao-token.js +200 -228
  117. package/dist/esm/apps/governance/state-machines/governance-simple.js +232 -232
  118. package/dist/esm/apps/governance/state-machines/governance-universal.js +65 -65
  119. package/dist/esm/apps/identity/constants.js +52 -21
  120. package/dist/esm/apps/identity/index.js +14 -9
  121. package/dist/esm/apps/identity/state-machines/identity-agent.js +125 -159
  122. package/dist/esm/apps/identity/state-machines/identity-oracle.js +159 -174
  123. package/dist/esm/apps/identity/state-machines/identity-registry.js +259 -0
  124. package/dist/esm/apps/identity/state-machines/identity-universal.js +52 -58
  125. package/dist/esm/apps/identity/state-machines/index.js +1 -0
  126. package/dist/esm/apps/index.js +9 -5
  127. package/dist/esm/apps/lending/assets.js +231 -0
  128. package/dist/esm/apps/lending/credit-scoring.js +81 -0
  129. package/dist/esm/apps/lending/eligibility.js +99 -0
  130. package/dist/esm/apps/lending/index.js +69 -0
  131. package/dist/esm/apps/lending/state-machines/index.js +5 -0
  132. package/dist/esm/apps/lending/state-machines/lending-zk-loan.js +430 -0
  133. package/dist/esm/apps/markets/index.js +11 -7
  134. package/dist/esm/apps/markets/state-machines/market-auction.js +117 -135
  135. package/dist/esm/apps/markets/state-machines/market-crowdfund.js +132 -142
  136. package/dist/esm/apps/markets/state-machines/market-group-buy.js +164 -185
  137. package/dist/esm/apps/markets/state-machines/market-prediction.js +227 -234
  138. package/dist/esm/apps/markets/state-machines/market-universal.js +66 -81
  139. package/dist/esm/apps/oracles/index.js +3 -3
  140. package/dist/esm/apps/privacy/index.js +56 -0
  141. package/dist/esm/apps/privacy/state-machines/index.js +6 -0
  142. package/dist/esm/apps/privacy/state-machines/mixer-ddhRing.js +282 -0
  143. package/dist/esm/apps/privacy/state-machines/note-pool.js +470 -0
  144. package/dist/esm/apps/staked-pool/assets.js +91 -0
  145. package/dist/esm/apps/staked-pool/base.js +493 -0
  146. package/dist/esm/apps/staked-pool/consumer.js +49 -0
  147. package/dist/esm/apps/staked-pool/index.js +60 -0
  148. package/dist/esm/apps/staked-pool/state-machines/index.js +6 -0
  149. package/dist/esm/apps/staked-pool/state-machines/staked-pool-base.js +46 -0
  150. package/dist/esm/apps/staked-pool/state-machines/staked-pool-oracle.js +127 -0
  151. package/dist/esm/generated/google/protobuf/struct.js +1 -1
  152. package/dist/esm/generated/google/protobuf/timestamp.js +1 -1
  153. package/dist/esm/generated/index.js +9 -5
  154. package/dist/esm/generated/openapi.js +5 -0
  155. package/dist/esm/generated/ottochain/apps/contracts/v1/contract.js +47 -47
  156. package/dist/esm/generated/ottochain/apps/corporate/v1/corporate.js +1 -1
  157. package/dist/esm/generated/ottochain/apps/governance/v1/governance.js +1 -1
  158. package/dist/esm/generated/ottochain/apps/identity/v1/attestation.js +1 -1
  159. package/dist/esm/generated/ottochain/apps/identity/v1/identity.js +115 -121
  160. package/dist/esm/generated/ottochain/apps/markets/v1/market.js +101 -101
  161. package/dist/esm/generated/ottochain/v1/common.js +1 -1
  162. package/dist/esm/generated/ottochain/v1/fiber.js +40 -2
  163. package/dist/esm/generated/ottochain/v1/messages.js +1 -1
  164. package/dist/esm/generated/ottochain/v1/records.js +1 -1
  165. package/dist/esm/index.js +28 -3
  166. package/dist/esm/openapi.js +1 -0
  167. package/dist/esm/ottochain/genesis-manifest.js +15 -9
  168. package/dist/esm/ottochain/index.js +2 -3
  169. package/dist/esm/ottochain/metagraph-client.js +81 -16
  170. package/dist/esm/ottochain/snapshot.js +6 -8
  171. package/dist/esm/ottochain/transaction.js +51 -3
  172. package/dist/esm/ottochain/types.js +15 -1
  173. package/dist/esm/privacy/index.js +6 -0
  174. package/dist/esm/privacy/sealed-bid.js +209 -0
  175. package/dist/esm/privacy/shield-app.js +127 -0
  176. package/dist/esm/schema/effects.js +145 -0
  177. package/dist/esm/schema/fiber-app.js +139 -8
  178. package/dist/esm/schema/guard-lint.js +337 -0
  179. package/dist/esm/schema/guards.js +228 -0
  180. package/dist/esm/signing.js +74 -0
  181. package/dist/esm/templates/asset-policy.js +182 -0
  182. package/dist/esm/templates/index.js +41 -0
  183. package/dist/esm/templates/machine.js +125 -0
  184. package/dist/esm/templates/migration.js +34 -0
  185. package/dist/esm/templates/state-shape.js +34 -0
  186. package/dist/esm/validation.js +1 -3
  187. package/dist/esm/verify.js +8 -2
  188. package/dist/esm/zk/commit.js +44 -0
  189. package/dist/esm/zk/guard.js +99 -0
  190. package/dist/esm/zk/index.js +19 -0
  191. package/dist/esm/zk/preimage.js +30 -0
  192. package/dist/esm/zk/prover.js +82 -0
  193. package/dist/esm/zk/registry.js +55 -0
  194. package/dist/esm/zk/types.js +25 -0
  195. package/dist/esm/zk/witness.js +15 -0
  196. package/dist/types/apps/compute/index.d.ts +176 -0
  197. package/dist/types/apps/compute/state-machines/compute-rule110.d.ts +157 -0
  198. package/dist/types/apps/compute/state-machines/index.d.ts +5 -0
  199. package/dist/types/apps/contracts/index.d.ts +81 -221
  200. package/dist/types/apps/contracts/state-machines/contract-agreement.d.ts +23 -98
  201. package/dist/types/apps/contracts/state-machines/contract-escrow.d.ts +49 -115
  202. package/dist/types/apps/contracts/state-machines/contract-universal.d.ts +4 -4
  203. package/dist/types/apps/corporate/index.d.ts +1176 -440
  204. package/dist/types/apps/corporate/state-machines/corp-board.d.ts +271 -135
  205. package/dist/types/apps/corporate/state-machines/corp-entity.d.ts +279 -74
  206. package/dist/types/apps/corporate/state-machines/corp-securities.d.ts +373 -149
  207. package/dist/types/apps/corporate/state-machines/corp-shareholders.d.ts +252 -80
  208. package/dist/types/apps/governance/index.d.ts +368 -470
  209. package/dist/types/apps/governance/state-machines/dao-multisig.d.ts +92 -107
  210. package/dist/types/apps/governance/state-machines/dao-reputation.d.ts +61 -85
  211. package/dist/types/apps/governance/state-machines/dao-single.d.ts +25 -47
  212. package/dist/types/apps/governance/state-machines/dao-token.d.ts +79 -68
  213. package/dist/types/apps/governance/state-machines/governance-simple.d.ts +95 -125
  214. package/dist/types/apps/governance/state-machines/governance-universal.d.ts +6 -6
  215. package/dist/types/apps/identity/constants.d.ts +33 -5
  216. package/dist/types/apps/identity/index.d.ts +415 -131
  217. package/dist/types/apps/identity/state-machines/identity-agent.d.ts +23 -23
  218. package/dist/types/apps/identity/state-machines/identity-oracle.d.ts +27 -98
  219. package/dist/types/apps/identity/state-machines/identity-registry.d.ts +379 -0
  220. package/dist/types/apps/identity/state-machines/identity-universal.d.ts +4 -4
  221. package/dist/types/apps/identity/state-machines/index.d.ts +1 -0
  222. package/dist/types/apps/index.d.ts +9 -5
  223. package/dist/types/apps/lending/assets.d.ts +258 -0
  224. package/dist/types/apps/lending/credit-scoring.d.ts +80 -0
  225. package/dist/types/apps/lending/eligibility.d.ts +83 -0
  226. package/dist/types/apps/lending/index.d.ts +556 -0
  227. package/dist/types/apps/lending/state-machines/index.d.ts +5 -0
  228. package/dist/types/apps/lending/state-machines/lending-zk-loan.d.ts +536 -0
  229. package/dist/types/apps/markets/index.d.ts +181 -276
  230. package/dist/types/apps/markets/state-machines/market-auction.d.ts +25 -49
  231. package/dist/types/apps/markets/state-machines/market-crowdfund.d.ts +35 -53
  232. package/dist/types/apps/markets/state-machines/market-group-buy.d.ts +35 -61
  233. package/dist/types/apps/markets/state-machines/market-prediction.d.ts +65 -86
  234. package/dist/types/apps/markets/state-machines/market-universal.d.ts +12 -12
  235. package/dist/types/apps/oracles/index.d.ts +1 -1
  236. package/dist/types/apps/privacy/index.d.ts +328 -0
  237. package/dist/types/apps/privacy/state-machines/index.d.ts +6 -0
  238. package/dist/types/apps/privacy/state-machines/mixer-ddhRing.d.ts +337 -0
  239. package/dist/types/apps/privacy/state-machines/note-pool.d.ts +196 -0
  240. package/dist/types/apps/staked-pool/assets.d.ts +53 -0
  241. package/dist/types/apps/staked-pool/base.d.ts +80 -0
  242. package/dist/types/apps/staked-pool/consumer.d.ts +29 -0
  243. package/dist/types/apps/staked-pool/index.d.ts +51 -0
  244. package/dist/types/apps/staked-pool/state-machines/index.d.ts +6 -0
  245. package/dist/types/apps/staked-pool/state-machines/staked-pool-base.d.ts +8 -0
  246. package/dist/types/apps/staked-pool/state-machines/staked-pool-oracle.d.ts +34 -0
  247. package/dist/types/generated/index.d.ts +5 -5
  248. package/dist/types/generated/openapi.d.ts +1270 -0
  249. package/dist/types/generated/ottochain/apps/contracts/v1/contract.d.ts +5 -5
  250. package/dist/types/generated/ottochain/apps/identity/v1/identity.d.ts +12 -12
  251. package/dist/types/generated/ottochain/apps/markets/v1/market.d.ts +11 -11
  252. package/dist/types/generated/ottochain/v1/fiber.d.ts +7 -0
  253. package/dist/types/index.d.ts +7 -3
  254. package/dist/types/openapi.d.ts +24 -0
  255. package/dist/types/ottochain/genesis-manifest.d.ts +11 -5
  256. package/dist/types/ottochain/index.d.ts +5 -6
  257. package/dist/types/ottochain/metagraph-client.d.ts +49 -7
  258. package/dist/types/ottochain/snapshot.d.ts +6 -6
  259. package/dist/types/ottochain/transaction.d.ts +41 -1
  260. package/dist/types/ottochain/types.d.ts +336 -31
  261. package/dist/types/privacy/index.d.ts +6 -0
  262. package/dist/types/privacy/sealed-bid.d.ts +348 -0
  263. package/dist/types/privacy/shield-app.d.ts +48 -0
  264. package/dist/types/schema/effects.d.ts +141 -0
  265. package/dist/types/schema/fiber-app.d.ts +282 -2
  266. package/dist/types/schema/guard-lint.d.ts +111 -0
  267. package/dist/types/schema/guards.d.ts +146 -0
  268. package/dist/types/signing.d.ts +45 -0
  269. package/dist/types/templates/asset-policy.d.ts +119 -0
  270. package/dist/types/templates/index.d.ts +26 -0
  271. package/dist/types/templates/machine.d.ts +139 -0
  272. package/dist/types/templates/migration.d.ts +34 -0
  273. package/dist/types/templates/state-shape.d.ts +30 -0
  274. package/dist/types/validation.d.ts +22 -217
  275. package/dist/types/verify.d.ts +4 -0
  276. package/dist/types/zk/commit.d.ts +28 -0
  277. package/dist/types/zk/guard.d.ts +46 -0
  278. package/dist/types/zk/index.d.ts +19 -0
  279. package/dist/types/zk/preimage.d.ts +10 -0
  280. package/dist/types/zk/prover.d.ts +34 -0
  281. package/dist/types/zk/registry.d.ts +34 -0
  282. package/dist/types/zk/types.d.ts +33 -0
  283. package/dist/types/zk/witness.d.ts +40 -0
  284. package/package.json +47 -15
  285. package/dist/cjs/ottochain/normalize.js +0 -186
  286. package/dist/esm/ottochain/normalize.js +0 -179
  287. package/dist/types/ottochain/normalize.d.ts +0 -79
@@ -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[];
@@ -192,10 +465,17 @@ export interface ProtoStateMachineDefinition {
192
465
  eventName: string;
193
466
  guard?: unknown;
194
467
  effect?: unknown;
195
- dependencies?: unknown[];
196
- emits?: unknown[];
468
+ dependencies: string[];
197
469
  }>;
198
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;
199
479
  }
200
480
  /**
201
481
  * Extract proto-compatible StateMachineDefinition from a FiberAppDefinition.
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Regression-prevention lint for OttoChain std-app fiber definitions.
3
+ *
4
+ * Purpose
5
+ * -------
6
+ * Catch — at *authoring* time — the classes of SDK↔chain drift that the chain
7
+ * accepts structurally but then silently mis-parses, drops, or evaluates to a
8
+ * dead (always-true / always-false / always-throw) guard. Without this lint
9
+ * those mistakes ship as live, exploitable holes or as silent data corruption
10
+ * because nothing in `defineFiberApp` / `toProtoDefinition` rejects them.
11
+ *
12
+ * The drift classes (cross-referenced to docs/reviews/fiber-app-alignment-audit-2026-06.md):
13
+ *
14
+ * A1 — `$timestamp` (and any non-injected `$`-key). `ReservedKeys` injects ONLY
15
+ * `$ordinal`, `$lastSnapshotHash`, `$epochProgress`. `{"var":"$timestamp"}`
16
+ * resolves to null → `0` in numeric contexts → deadline guards die silently.
17
+ *
18
+ * A2 — Nonexistent JLVM opcodes used as operator tags: `size`, `getKey`,
19
+ * `setKey`, `deleteKey`. metakit decodes an unknown single-key object as a
20
+ * LITERAL Map, not an operator, so the guard is always-true/false and the
21
+ * effect writes a junk key. (Canonical good set: `KNOWN_OPERATORS`.)
22
+ *
23
+ * A3 — SDK directives the chain's `toProtoDefinition` silently drops:
24
+ * transition-level `emits` / `spawns`, and object-form `dependencies`
25
+ * entries `{machine,instanceRef,requiredState}` (chain parses `Set[UUID]`).
26
+ * Authors believe these gate/emit; on-chain they evaporate.
27
+ *
28
+ * per-context — `{"var":"witness.*"}` in a fiber TRANSITION. `witness` is only
29
+ * injected in ASSET-guard contexts; a transition gets `event` (the proof
30
+ * rides under `event.witness.*`). Reading `witness.*` resolves to null →
31
+ * fail-closed (zk gate un-passable) or silently bypassed.
32
+ *
33
+ * leading-dot — `{"var":".foo"}` resolves to null on chain.
34
+ *
35
+ * This is a STANDALONE validator. It is deliberately NOT wired into
36
+ * `defineFiberApp` / `toProtoDefinition`: doing so would break the build until
37
+ * every app is remediated. Run it via `scripts/lint-apps.mjs`.
38
+ */
39
+ import type { FiberAppDefinition } from './fiber-app.js';
40
+ export type LintSeverity = 'error' | 'warn';
41
+ export interface LintViolation {
42
+ /** App identifier (`metadata.app/metadata.type` or `metadata.name`), when known. */
43
+ app?: string;
44
+ /** `eventName` (or `from→to`) of the offending transition, when applicable. */
45
+ transition?: string;
46
+ severity: LintSeverity;
47
+ /** Stable machine-readable rule code (see {@link LINT_CODES}). */
48
+ code: string;
49
+ /** Human-readable explanation including the correct alternative. */
50
+ message: string;
51
+ /** JSON-ish path to the offending node, e.g. `transitions[3].guard.or[0].var`. */
52
+ path: string;
53
+ }
54
+ /** Stable rule codes — referenced by tests and by report tooling. */
55
+ export declare const LINT_CODES: {
56
+ readonly UNKNOWN_RESERVED_VAR: "unknown-reserved-var";
57
+ readonly UNKNOWN_OPERATOR: "unknown-operator";
58
+ readonly WITNESS_IN_TRANSITION: "witness-in-transition";
59
+ readonly DROPPED_DIRECTIVE: "dropped-directive";
60
+ readonly LEADING_DOT_VAR: "leading-dot-var";
61
+ };
62
+ /**
63
+ * The ONLY `$`-prefixed keys the engine injects (`ReservedKeys`). Anything else
64
+ * (`$timestamp`, `$now`, ...) resolves to null on chain.
65
+ */
66
+ export declare const INJECTED_RESERVED_VARS: ReadonlySet<string>;
67
+ /**
68
+ * Tags that LOOK like opcodes and appear in real definitions but are NOT valid
69
+ * JLVM operators — metakit mis-decodes each as a literal Map. These are always
70
+ * flagged as errors regardless of position (they are not plausible data fields).
71
+ * Mapped to the correct replacement opcode for the message.
72
+ */
73
+ export declare const KNOWN_BAD_OPERATORS: ReadonlyMap<string, string>;
74
+ interface WalkContext {
75
+ app?: string;
76
+ transition?: string;
77
+ /**
78
+ * When true, this transition expression runs in a context where `witness` is
79
+ * NOT injected (a fiber transition guard/effect). Reading `witness.*` here is
80
+ * a bug (rule 3). Asset-guard contexts would set this false (not walked here).
81
+ */
82
+ flagWitness: boolean;
83
+ }
84
+ /**
85
+ * Recursively lint a single JSON-Logic expression (a guard or an effect, or any
86
+ * sub-node). Walks every nested operand. Pushes a {@link LintViolation} for each
87
+ * rule-1 / rule-2 / rule-3 / rule-5 hit found at or below `node`.
88
+ *
89
+ * `inDataLiteral` tracks whether `node` sits in a position the evaluator treats
90
+ * as DATA rather than as an expression to evaluate (e.g. the 2nd operand of
91
+ * `merge`/`cat`, or a value nested inside such an operand). In a data-literal
92
+ * position an unknown single-key object is a legitimate field map, so the
93
+ * *generic* unknown-operator warning is suppressed there — but `$`-var keys,
94
+ * leading-dot vars, witness reads, and the known-BAD opcode tags are still
95
+ * flagged (those are bugs wherever they appear).
96
+ */
97
+ export declare function lintGuardExpression(node: unknown, ctx: WalkContext, path: string, inDataLiteral?: boolean): LintViolation[];
98
+ /**
99
+ * Lint a complete fiber app definition. Walks every transition guard + effect
100
+ * (rules 1/2/3/5) and every transition's structural directives (rule 4), plus a
101
+ * light pass over `states` to catch stray reserved-key / operator drift embedded
102
+ * in state metadata. Returns ALL violations (errors and warnings); callers
103
+ * decide the exit policy (e.g. fail on any `error`).
104
+ */
105
+ export declare function lintFiberApp(def: FiberAppDefinition): LintViolation[];
106
+ /**
107
+ * Convenience: lint many apps at once, returning a flat list. Each app's
108
+ * violations already carry its `app` label.
109
+ */
110
+ export declare function lintFiberApps(defs: readonly FiberAppDefinition[]): LintViolation[];
111
+ export {};
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Canonical authorization-guard builders — bind "who may act" to the CHAIN-VERIFIED signer of the op,
3
+ * never to an attacker-supplied payload field.
4
+ *
5
+ * The forgeable anti-pattern (security audit class F1): `{"===":[{"var":"event.agent"}, {"var":"state.party"}]}`.
6
+ * The fiber engine injects `event` as the RAW transition payload (ContextProvider: `EVENT -> payload`),
7
+ * so `event.agent` is whatever the submitter wrote — a different party's address forges authorization.
8
+ * The chain ALSO injects `proofs` = `[{address, id, signature}]` where `address = id.toAddress` (the
9
+ * VERIFIED signer addresses). Authorization must bind to THAT. For ASSET ops (mint/burn/morphism) the
10
+ * context has no `event`/`proofs`; it injects `signers` (an array of verified address strings) instead.
11
+ *
12
+ * Use these so the safe pattern is consistent, greppable, and impossible to get subtly wrong.
13
+ */
14
+ /** A JSON-Logic guard expression (plain JSON). */
15
+ export type GuardRule = Record<string, unknown>;
16
+ /**
17
+ * FIBER-transition authorization: the pinned `partyVar` (a `state` path holding an address, e.g.
18
+ * `"state.borrower"`) MUST be among the op's verified signers (`proofs[].address`). The replay-safe
19
+ * replacement for `{"===":[{"var":"event.agent"}, {"var":partyVar}]}`.
20
+ */
21
+ export declare const signerIsParty: (partyVar: string) => GuardRule;
22
+ /** FIBER-transition authorization where ANY of the pinned parties signed (e.g. borrower OR lender). */
23
+ export declare const signerIsAnyParty: (partyVars: string[]) => GuardRule;
24
+ /**
25
+ * FIBER-transition authorization where the actor must be a MEMBER of a pinned set: at least one
26
+ * VERIFIED signer is in the `setVar` array (e.g. `"state.signers"`, `"state.members"`, `"state.oracles"`).
27
+ * The replay-safe replacement for `{"in":[{"var":"event.agent"}, {"var":setVar}]}`.
28
+ */
29
+ export declare const signerInSet: (setVar: string) => GuardRule;
30
+ /**
31
+ * FIBER-transition ANTI-SELF guard: NO verified signer is the pinned party (e.g. a proposal author may
32
+ * not vote on their own proposal). The replay-safe replacement for `{"!==":[{"var":"event.agent"}, {"var":partyVar}]}`.
33
+ */
34
+ export declare const signerIsNotParty: (partyVar: string) => GuardRule;
35
+ /**
36
+ * FIBER-transition authorization / dedup over a state MAP keyed by address: at least one VERIFIED signer
37
+ * is a key in `mapVar` (e.g. `"state.members"`, `"state.balances"`). The replay-safe replacement for the
38
+ * forgeable `{"getKey":[{"var":mapVar}, {"var":"event.agent"}]}` membership/presence check (note metakit
39
+ * has no `getKey`; use `get`/`has`). For a "no signer has acted yet" dedup, negate: `{"!":[signerHasEntry(...)]}`.
40
+ * For a per-actor VALUE threshold (e.g. balance >= N), build the `some` directly:
41
+ * `{"some":[{"map":[proofs,address]},{">=":[{"get":[mapVar,{"var":""}]}, N]}]}`.
42
+ */
43
+ export declare const signerHasEntry: (mapVar: string) => GuardRule;
44
+ /**
45
+ * ASSET-op authorization (mintPolicy / burnPolicy / MorphismSpec.guard): the address at `addressVar`
46
+ * (e.g. `"holder.Wallet.address"`) MUST be among the op's verified `signers`. The asset context has no
47
+ * `event` or `proofs` — it injects `signers` directly.
48
+ */
49
+ export declare const assetSignerIs: (addressVar: string) => GuardRule;
50
+ /**
51
+ * EFFECT-KEY BINDING: prove the event's claimed actor (`actorVar`, default `event.agent`) is a
52
+ * CHAIN-VERIFIED signer, so that field is SAFE to use as a dynamic map key / array element in the
53
+ * EFFECT (`{"set":[map,{"var":"event.agent"},v]}`, `{"cat":[arr,[{"var":"event.agent"}]]}`).
54
+ *
55
+ * This is the coupling clause for the map-write remediation: a guard may authorize via membership /
56
+ * balance / reputation, but if the EFFECT writes under `event.agent` WITHOUT this clause, an attacker
57
+ * sets `event.agent` to a victim's address and writes under the victim's key (security class S1).
58
+ * Pair it with the authorization check expressed on the SAME `actorVar` — together they prove the actor
59
+ * both signed and is authorized, and the effect can only write under that one verified key.
60
+ * Structurally identical to {@link signerIsParty}; named for intent + greppability at write sites.
61
+ */
62
+ export declare const actorIsSigner: (actorVar?: string) => GuardRule;
63
+ /**
64
+ * EFFECT-KEY-BINDING membership: the event's claimed actor (`actorVar`, default `event.agent`) is BOTH
65
+ * a CHAIN-VERIFIED signer AND a member of the pinned set `setVar` (e.g. `"state.signers"`,
66
+ * `"state.members"`). Use when the EFFECT writes a map/array keyed by that actor and authorization is
67
+ * set-membership. It proves the EXACT actor whose key is written both signed and is authorized — closing
68
+ * the S1 forge AND the subtler gap {@link signerInSet} leaves open: `signerInSet` only proves SOME
69
+ * verified signer is a member, so an op co-signed by an authorized signer could still write a DIFFERENT
70
+ * verified-but-unauthorized address as the key (padding a signature/vote tally). `actorInSet` pins both
71
+ * to the same `actorVar`.
72
+ */
73
+ export declare const actorInSet: (setVar: string, actorVar?: string) => GuardRule;
74
+ /**
75
+ * EFFECT-KEY-BINDING map membership: the claimed actor (`actorVar`, default `event.agent`) is BOTH a
76
+ * CHAIN-VERIFIED signer AND a key in the pinned state MAP `mapVar` (e.g. `"state.members"`,
77
+ * `"state.balances"`). The map analog of {@link actorInSet} — use it when the membership set is a dict
78
+ * keyed by address, where `in` does not apply and `has` checks key presence. Use when the EFFECT writes
79
+ * `mapVar` (or a per-actor tally) keyed by that actor: it proves the EXACT written key both signed and
80
+ * is an authorized member, closing the vote/signature-stuffing gap that bare {@link signerHasEntry}
81
+ * leaves open (which only proves SOME verified signer is a key, not that the written key is).
82
+ */
83
+ export declare const actorHasEntry: (mapVar: string, actorVar?: string) => GuardRule;
84
+ /**
85
+ * IDENTITY-REGISTRY reputation gate: at least one VERIFIED signer has a reputation in the registry map
86
+ * at `repMapVar` (a declared-dependency read, e.g. `"machines.<registryDep>.state.reputations"`, shaped
87
+ * `{ <address>: int }`) that is `>=` the bar read from `thresholdVar` (a state path, e.g.
88
+ * `"state.voteThreshold"`). A missing entry reads as null → 0 numerically, so unregistered signers
89
+ * fail-closed for any positive bar. The replay-safe replacement for the forgeable
90
+ * `{">=":[{"var":"event.agentReputation"}, bar]}` (security class S1). See
91
+ * docs/design/app-hardening-identity-integration.md §3–§4.1.
92
+ */
93
+ export declare const signerHasReputation: (repMapVar: string, thresholdVar: string) => GuardRule;
94
+ /**
95
+ * IDENTITY-REGISTRY role gate: at least one VERIFIED signer holds an active role attestation, i.e. is a
96
+ * key in the registry's flat per-role map at `roleMapVar` (a declared-dependency read, e.g.
97
+ * `"machines.<registryDep>.state.arbiters"` / `".slashers"` / `".issuers"` / `".boardMembers"`, each
98
+ * shaped `{ <address>: true }`). The replay-safe replacement for bare `event.judicialRuling` / role
99
+ * escapes and `{"==":[1,1]}` missing-auth (security class S2). Roles are FLAT per-role maps (not a
100
+ * nested `roles[addr][ROLE]`) because metakit `get`/`has` on a null inner map ERROR rather than
101
+ * returning null; a flat map keeps the read total + fail-closed. See app-hardening §4.2.
102
+ */
103
+ export declare const signerHasRole: (roleMapVar: string) => GuardRule;
104
+ /**
105
+ * DYNAMIC identity-registry reputation gate — for when the registry instance is bound at RUNTIME via the
106
+ * fiber-engine `_addDependency` directive (#24) rather than hardcoded into the `machines.<uuid>` path.
107
+ * `registryIdVar` is a state/event path holding the registry fiber id (e.g. `"state.registryId"`); the
108
+ * read addresses `machines[<that id>].state.reputations[<signer>]` with dynamic `get`s. Guarded by a
109
+ * presence check so an UNBOUND registry yields a clean `false` (fail-closed) instead of an evaluation
110
+ * error. REQUIRES the registry dependency to have been added in a PRIOR transition (`_addDependency`),
111
+ * because the `machines` context is built before the effect runs (two-phase: bind, then read).
112
+ */
113
+ export declare const signerHasReputationVia: (registryIdVar: string, thresholdVar: string) => GuardRule;
114
+ /**
115
+ * DYNAMIC identity-registry role gate — the runtime-bound (`_addDependency`, #24) counterpart of
116
+ * {@link signerHasRole}. `registryIdVar` is a state/event path holding the registry fiber id;
117
+ * `roleField` is the registry's flat per-role state map name (`"arbiters"` / `"slashers"` / `"issuers"` /
118
+ * `"boardMembers"` — see REGISTRY_ROLE_MAP). Reads `machines[<id>].state.<roleField>[<signer>]`, guarded
119
+ * by a presence check so an UNBOUND registry yields a clean `false`. Same two-phase requirement as
120
+ * {@link signerHasReputationVia}.
121
+ */
122
+ export declare const signerHasRoleVia: (registryIdVar: string, roleField: string) => GuardRule;
123
+ /**
124
+ * CROSS-FIBER STATE GATE — assert a RUNTIME-bound dependency fiber is in a required lifecycle state. The
125
+ * replay-safe replacement for the dropped object-form dependency
126
+ * `{machine, instanceRef, requiredState}` (which the chain silently drops — `requiredState` gating never
127
+ * happens). `refVar` is a state/event path holding the dependency's fiber id; reads
128
+ * `machines[<refVar>].currentStateId == requiredState`, guarded by a presence check so an UNBOUND
129
+ * dependency yields a clean `false` (fail-closed). TWO-PHASE (#24): the dependency fiber must have been
130
+ * bound by an `_addDependency` in a PRIOR transition (the `machines` context is built before the effect),
131
+ * so a single gated transition is split into a bind step then this assert step. See
132
+ * docs/design/app-hardening-identity-integration.md §5–§6.
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;
146
+ export declare const depInState: (refVar: string, requiredState: string) => GuardRule;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * DataUpdate Signing Wrappers — dropNulls applied internally
3
+ *
4
+ * Metakit (>= 1.8) computes content hashes by recursively dropping
5
+ * null-valued OBJECT fields (array nulls are preserved) before RFC 8785
6
+ * canonicalization (`JsonBinaryCodec.dropNulls`). This makes
7
+ * `Option = None` indistinguishable from an absent field, so schema
8
+ * evolution never changes prior hashes.
9
+ *
10
+ * The upstream `@constellation-network/metagraph-sdk` signs over the
11
+ * payload as-is, so a payload containing explicit nulls would be signed
12
+ * over different bytes than the metagraph hashes — and the node rejects
13
+ * the signature (HTTP 400).
14
+ *
15
+ * These wrappers shadow the upstream dataUpdate signing surface and apply
16
+ * `dropNulls` internally, unconditionally. Standard-mode signing
17
+ * (currency transactions etc.) is passed through unchanged.
18
+ */
19
+ import type { SignatureProof, Signed, SigningOptions } from '@constellation-network/metagraph-sdk';
20
+ /**
21
+ * Sign data as a DataUpdate, hashing over null-dropped canonical bytes.
22
+ *
23
+ * Applies `dropNulls` internally so that explicit-null and absent optional
24
+ * fields produce identical signatures, matching metakit's content-hash rule
25
+ * (drop null object fields, preserve array nulls, then RFC 8785).
26
+ */
27
+ export declare function signDataUpdate<T>(data: T, privateKey: string): SignatureProof;
28
+ /**
29
+ * Create a signed object. In `dataUpdate` mode the signature is computed
30
+ * over the null-dropped canonical bytes (the returned `value` is the
31
+ * caller's original payload, untouched).
32
+ */
33
+ export declare function createSignedObject<T>(value: T, privateKey: string, options?: SigningOptions): Signed<T>;
34
+ /**
35
+ * Add an additional signature to an existing signed object. In
36
+ * `dataUpdate` mode the new signature is computed over the null-dropped
37
+ * canonical bytes of `signed.value`.
38
+ */
39
+ export declare function addSignature<T>(signed: Signed<T>, privateKey: string, options?: SigningOptions): Signed<T>;
40
+ /**
41
+ * Create a signed object with multiple signatures at once. In
42
+ * `dataUpdate` mode all signatures are computed over the null-dropped
43
+ * canonical bytes (the returned `value` is the caller's original payload).
44
+ */
45
+ export declare function batchSign<T>(value: T, privateKeys: string[], options?: SigningOptions): Signed<T>;