@ottochain/sdk 2.2.5 → 2.4.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 (222) hide show
  1. package/dist/cjs/apps/contracts/index.js +15 -8
  2. package/dist/cjs/apps/contracts/state-machines/contract-agreement.js +89 -46
  3. package/dist/cjs/apps/contracts/state-machines/contract-escrow.js +152 -45
  4. package/dist/cjs/apps/contracts/state-machines/contract-universal.js +40 -8
  5. package/dist/cjs/apps/corporate/index.js +2 -2
  6. package/dist/cjs/apps/corporate/state-machines/corp-board.js +169 -59
  7. package/dist/cjs/apps/corporate/state-machines/corp-entity.js +245 -47
  8. package/dist/cjs/apps/corporate/state-machines/corp-securities.js +407 -99
  9. package/dist/cjs/apps/corporate/state-machines/corp-shareholders.js +151 -37
  10. package/dist/cjs/apps/governance/index.js +14 -14
  11. package/dist/cjs/apps/governance/state-machines/dao-multisig.js +85 -43
  12. package/dist/cjs/apps/governance/state-machines/dao-reputation.js +73 -43
  13. package/dist/cjs/apps/governance/state-machines/dao-single.js +55 -14
  14. package/dist/cjs/apps/governance/state-machines/dao-token.js +103 -45
  15. package/dist/cjs/apps/governance/state-machines/governance-simple.js +129 -65
  16. package/dist/cjs/apps/governance/state-machines/governance-universal.js +29 -5
  17. package/dist/cjs/apps/identity/constants.js +55 -14
  18. package/dist/cjs/apps/identity/index.js +27 -11
  19. package/dist/cjs/apps/identity/state-machines/identity-agent.js +57 -9
  20. package/dist/cjs/apps/identity/state-machines/identity-oracle.js +70 -27
  21. package/dist/cjs/apps/identity/state-machines/identity-registry.js +288 -0
  22. package/dist/cjs/apps/identity/state-machines/identity-universal.js +30 -6
  23. package/dist/cjs/apps/identity/state-machines/index.js +3 -1
  24. package/dist/cjs/apps/index.js +19 -8
  25. package/dist/cjs/apps/lending/assets.js +223 -0
  26. package/dist/cjs/apps/lending/credit-scoring.js +87 -0
  27. package/dist/cjs/apps/lending/eligibility.js +121 -0
  28. package/dist/cjs/apps/lending/index.js +91 -0
  29. package/dist/cjs/apps/lending/state-machines/index.js +9 -0
  30. package/dist/cjs/apps/lending/state-machines/lending-zk-loan.js +412 -0
  31. package/dist/cjs/apps/markets/index.js +21 -11
  32. package/dist/cjs/apps/markets/state-machines/market-auction.js +44 -19
  33. package/dist/cjs/apps/markets/state-machines/market-crowdfund.js +54 -29
  34. package/dist/cjs/apps/markets/state-machines/market-group-buy.js +53 -31
  35. package/dist/cjs/apps/markets/state-machines/market-prediction.js +120 -61
  36. package/dist/cjs/apps/markets/state-machines/market-universal.js +50 -10
  37. package/dist/cjs/apps/oracles/index.js +2 -2
  38. package/dist/cjs/errors.js +3 -3
  39. package/dist/cjs/generated/google/protobuf/struct.js +4 -4
  40. package/dist/cjs/generated/index.js +11 -7
  41. package/dist/cjs/generated/openapi.js +6 -0
  42. package/dist/cjs/generated/ottochain/apps/contracts/v1/contract.js +50 -50
  43. package/dist/cjs/generated/ottochain/apps/corporate/v1/corporate.js +19 -20
  44. package/dist/cjs/generated/ottochain/apps/governance/v1/governance.js +13 -13
  45. package/dist/cjs/generated/ottochain/apps/identity/v1/attestation.js +4 -4
  46. package/dist/cjs/generated/ottochain/apps/identity/v1/identity.js +124 -130
  47. package/dist/cjs/generated/ottochain/apps/markets/v1/market.js +107 -107
  48. package/dist/cjs/generated/ottochain/v1/common.js +1722 -1
  49. package/dist/cjs/generated/ottochain/v1/fiber.js +355 -5
  50. package/dist/cjs/generated/ottochain/v1/messages.js +775 -3
  51. package/dist/cjs/generated/ottochain/v1/records.js +350 -3
  52. package/dist/cjs/index.js +45 -7
  53. package/dist/cjs/openapi.js +2 -0
  54. package/dist/cjs/ottochain/drop-nulls.js +1 -2
  55. package/dist/cjs/ottochain/genesis-manifest.js +193 -0
  56. package/dist/cjs/ottochain/index.js +27 -13
  57. package/dist/cjs/ottochain/metagraph-client.js +65 -8
  58. package/dist/cjs/ottochain/snapshot.js +11 -12
  59. package/dist/cjs/ottochain/transaction.js +57 -14
  60. package/dist/cjs/ottochain/types.js +19 -1
  61. package/dist/cjs/privacy/index.js +14 -0
  62. package/dist/cjs/privacy/sealed-bid.js +210 -0
  63. package/dist/cjs/privacy/shield-app.js +131 -0
  64. package/dist/cjs/schema/effects.js +40 -0
  65. package/dist/cjs/schema/fiber-app.js +19 -13
  66. package/dist/cjs/schema/guard-lint.js +352 -0
  67. package/dist/cjs/schema/guards.js +246 -0
  68. package/dist/cjs/signing.js +80 -0
  69. package/dist/cjs/types.js +2 -3
  70. package/dist/cjs/validation.js +8 -8
  71. package/dist/cjs/verify.js +9 -4
  72. package/dist/cjs/zk/commit.js +53 -0
  73. package/dist/cjs/zk/guard.js +107 -0
  74. package/dist/cjs/zk/index.js +48 -0
  75. package/dist/cjs/zk/preimage.js +37 -0
  76. package/dist/cjs/zk/prover.js +87 -0
  77. package/dist/cjs/zk/registry.js +62 -0
  78. package/dist/cjs/zk/types.js +28 -0
  79. package/dist/cjs/zk/witness.js +19 -0
  80. package/dist/esm/apps/contracts/index.js +7 -3
  81. package/dist/esm/apps/contracts/state-machines/contract-agreement.js +89 -46
  82. package/dist/esm/apps/contracts/state-machines/contract-escrow.js +152 -45
  83. package/dist/esm/apps/contracts/state-machines/contract-universal.js +40 -8
  84. package/dist/esm/apps/corporate/state-machines/corp-board.js +169 -59
  85. package/dist/esm/apps/corporate/state-machines/corp-entity.js +245 -47
  86. package/dist/esm/apps/corporate/state-machines/corp-securities.js +407 -99
  87. package/dist/esm/apps/corporate/state-machines/corp-shareholders.js +151 -37
  88. package/dist/esm/apps/governance/state-machines/dao-multisig.js +85 -43
  89. package/dist/esm/apps/governance/state-machines/dao-reputation.js +73 -43
  90. package/dist/esm/apps/governance/state-machines/dao-single.js +55 -14
  91. package/dist/esm/apps/governance/state-machines/dao-token.js +103 -45
  92. package/dist/esm/apps/governance/state-machines/governance-simple.js +129 -65
  93. package/dist/esm/apps/governance/state-machines/governance-universal.js +29 -5
  94. package/dist/esm/apps/identity/constants.js +51 -12
  95. package/dist/esm/apps/identity/index.js +12 -7
  96. package/dist/esm/apps/identity/state-machines/identity-agent.js +57 -9
  97. package/dist/esm/apps/identity/state-machines/identity-oracle.js +70 -27
  98. package/dist/esm/apps/identity/state-machines/identity-registry.js +285 -0
  99. package/dist/esm/apps/identity/state-machines/identity-universal.js +30 -6
  100. package/dist/esm/apps/identity/state-machines/index.js +1 -0
  101. package/dist/esm/apps/index.js +1 -0
  102. package/dist/esm/apps/lending/assets.js +207 -0
  103. package/dist/esm/apps/lending/credit-scoring.js +81 -0
  104. package/dist/esm/apps/lending/eligibility.js +115 -0
  105. package/dist/esm/apps/lending/index.js +69 -0
  106. package/dist/esm/apps/lending/state-machines/index.js +5 -0
  107. package/dist/esm/apps/lending/state-machines/lending-zk-loan.js +409 -0
  108. package/dist/esm/apps/markets/index.js +8 -4
  109. package/dist/esm/apps/markets/state-machines/market-auction.js +44 -19
  110. package/dist/esm/apps/markets/state-machines/market-crowdfund.js +54 -29
  111. package/dist/esm/apps/markets/state-machines/market-group-buy.js +53 -31
  112. package/dist/esm/apps/markets/state-machines/market-prediction.js +120 -61
  113. package/dist/esm/apps/markets/state-machines/market-universal.js +50 -10
  114. package/dist/esm/generated/index.js +9 -5
  115. package/dist/esm/generated/openapi.js +5 -0
  116. package/dist/esm/generated/ottochain/apps/contracts/v1/contract.js +46 -46
  117. package/dist/esm/generated/ottochain/apps/identity/v1/identity.js +114 -120
  118. package/dist/esm/generated/ottochain/apps/markets/v1/market.js +100 -100
  119. package/dist/esm/generated/ottochain/v1/common.js +1718 -0
  120. package/dist/esm/generated/ottochain/v1/fiber.js +351 -1
  121. package/dist/esm/generated/ottochain/v1/messages.js +774 -2
  122. package/dist/esm/generated/ottochain/v1/records.js +349 -2
  123. package/dist/esm/index.js +23 -2
  124. package/dist/esm/openapi.js +1 -0
  125. package/dist/esm/ottochain/genesis-manifest.js +189 -0
  126. package/dist/esm/ottochain/index.js +4 -3
  127. package/dist/esm/ottochain/metagraph-client.js +65 -8
  128. package/dist/esm/ottochain/snapshot.js +4 -4
  129. package/dist/esm/ottochain/transaction.js +43 -3
  130. package/dist/esm/ottochain/types.js +18 -0
  131. package/dist/esm/privacy/index.js +6 -0
  132. package/dist/esm/privacy/sealed-bid.js +206 -0
  133. package/dist/esm/privacy/shield-app.js +127 -0
  134. package/dist/esm/schema/effects.js +35 -0
  135. package/dist/esm/schema/fiber-app.js +13 -6
  136. package/dist/esm/schema/guard-lint.js +346 -0
  137. package/dist/esm/schema/guards.js +229 -0
  138. package/dist/esm/signing.js +74 -0
  139. package/dist/esm/verify.js +8 -2
  140. package/dist/esm/zk/commit.js +44 -0
  141. package/dist/esm/zk/guard.js +99 -0
  142. package/dist/esm/zk/index.js +19 -0
  143. package/dist/esm/zk/preimage.js +30 -0
  144. package/dist/esm/zk/prover.js +82 -0
  145. package/dist/esm/zk/registry.js +55 -0
  146. package/dist/esm/zk/types.js +25 -0
  147. package/dist/esm/zk/witness.js +15 -0
  148. package/dist/types/apps/contracts/index.d.ts +159 -227
  149. package/dist/types/apps/contracts/state-machines/contract-agreement.d.ts +50 -101
  150. package/dist/types/apps/contracts/state-machines/contract-escrow.d.ts +86 -120
  151. package/dist/types/apps/contracts/state-machines/contract-universal.d.ts +20 -4
  152. package/dist/types/apps/corporate/index.d.ts +1040 -304
  153. package/dist/types/apps/corporate/state-machines/corp-board.d.ts +188 -52
  154. package/dist/types/apps/corporate/state-machines/corp-entity.d.ts +267 -62
  155. package/dist/types/apps/corporate/state-machines/corp-securities.d.ts +355 -131
  156. package/dist/types/apps/corporate/state-machines/corp-shareholders.d.ts +225 -53
  157. package/dist/types/apps/governance/index.d.ts +396 -417
  158. package/dist/types/apps/governance/state-machines/dao-multisig.d.ts +92 -95
  159. package/dist/types/apps/governance/state-machines/dao-reputation.d.ts +57 -69
  160. package/dist/types/apps/governance/state-machines/dao-single.d.ts +40 -50
  161. package/dist/types/apps/governance/state-machines/dao-token.d.ts +80 -53
  162. package/dist/types/apps/governance/state-machines/governance-simple.d.ts +107 -121
  163. package/dist/types/apps/governance/state-machines/governance-universal.d.ts +17 -5
  164. package/dist/types/apps/identity/constants.d.ts +32 -4
  165. package/dist/types/apps/identity/index.d.ts +449 -100
  166. package/dist/types/apps/identity/state-machines/identity-agent.d.ts +30 -0
  167. package/dist/types/apps/identity/state-machines/identity-oracle.d.ts +41 -87
  168. package/dist/types/apps/identity/state-machines/identity-registry.d.ts +379 -0
  169. package/dist/types/apps/identity/state-machines/identity-universal.d.ts +15 -0
  170. package/dist/types/apps/identity/state-machines/index.d.ts +1 -0
  171. package/dist/types/apps/index.d.ts +1 -0
  172. package/dist/types/apps/lending/assets.d.ts +258 -0
  173. package/dist/types/apps/lending/credit-scoring.d.ts +80 -0
  174. package/dist/types/apps/lending/eligibility.d.ts +83 -0
  175. package/dist/types/apps/lending/index.d.ts +548 -0
  176. package/dist/types/apps/lending/state-machines/index.d.ts +5 -0
  177. package/dist/types/apps/lending/state-machines/lending-zk-loan.d.ts +528 -0
  178. package/dist/types/apps/markets/index.d.ts +184 -204
  179. package/dist/types/apps/markets/state-machines/market-auction.d.ts +25 -37
  180. package/dist/types/apps/markets/state-machines/market-crowdfund.d.ts +26 -34
  181. package/dist/types/apps/markets/state-machines/market-group-buy.d.ts +31 -43
  182. package/dist/types/apps/markets/state-machines/market-prediction.d.ts +67 -72
  183. package/dist/types/apps/markets/state-machines/market-universal.d.ts +30 -10
  184. package/dist/types/generated/index.d.ts +5 -5
  185. package/dist/types/generated/openapi.d.ts +1257 -0
  186. package/dist/types/generated/ottochain/apps/contracts/v1/contract.d.ts +5 -5
  187. package/dist/types/generated/ottochain/apps/identity/v1/identity.d.ts +12 -12
  188. package/dist/types/generated/ottochain/apps/markets/v1/market.d.ts +11 -11
  189. package/dist/types/generated/ottochain/v1/common.d.ts +228 -0
  190. package/dist/types/generated/ottochain/v1/fiber.d.ts +32 -1
  191. package/dist/types/generated/ottochain/v1/messages.d.ts +84 -0
  192. package/dist/types/generated/ottochain/v1/records.d.ts +34 -0
  193. package/dist/types/index.d.ts +8 -2
  194. package/dist/types/openapi.d.ts +22 -0
  195. package/dist/types/ottochain/genesis-manifest.d.ts +130 -0
  196. package/dist/types/ottochain/index.d.ts +6 -5
  197. package/dist/types/ottochain/metagraph-client.d.ts +49 -7
  198. package/dist/types/ottochain/snapshot.d.ts +6 -6
  199. package/dist/types/ottochain/transaction.d.ts +33 -1
  200. package/dist/types/ottochain/types.d.ts +602 -11
  201. package/dist/types/privacy/index.d.ts +6 -0
  202. package/dist/types/privacy/sealed-bid.d.ts +348 -0
  203. package/dist/types/privacy/shield-app.d.ts +48 -0
  204. package/dist/types/schema/effects.d.ts +34 -0
  205. package/dist/types/schema/fiber-app.d.ts +41 -3
  206. package/dist/types/schema/guard-lint.d.ts +111 -0
  207. package/dist/types/schema/guards.d.ts +134 -0
  208. package/dist/types/signing.d.ts +45 -0
  209. package/dist/types/validation.d.ts +22 -217
  210. package/dist/types/verify.d.ts +4 -0
  211. package/dist/types/zk/commit.d.ts +28 -0
  212. package/dist/types/zk/guard.d.ts +46 -0
  213. package/dist/types/zk/index.d.ts +19 -0
  214. package/dist/types/zk/preimage.d.ts +10 -0
  215. package/dist/types/zk/prover.d.ts +34 -0
  216. package/dist/types/zk/registry.d.ts +34 -0
  217. package/dist/types/zk/types.d.ts +33 -0
  218. package/dist/types/zk/witness.d.ts +40 -0
  219. package/package.json +52 -35
  220. package/dist/cjs/ottochain/normalize.js +0 -186
  221. package/dist/esm/ottochain/normalize.js +0 -179
  222. package/dist/types/ottochain/normalize.d.ts +0 -79
@@ -1,4 +1,6 @@
1
1
  import { defineFiberApp } from "../../../schema/fiber-app.js";
2
+ import { signerIsParty, depInState } from "../../../schema/guards.js";
3
+ import { addDependency } from "../../../schema/effects.js";
2
4
  /**
3
5
  * Securities state machine tracking the lifecycle of equity from authorization through issuance, transfer, and retirement.
4
6
  * Manages stock certificates, book entry positions, and restricted securities.
@@ -32,6 +34,7 @@ export const corpSecuritiesDef = defineFiberApp({
32
34
  required: [
33
35
  "securityId",
34
36
  "entityId",
37
+ "issuerAddress",
35
38
  "shareClass",
36
39
  "shareClassName",
37
40
  "shareCount",
@@ -48,6 +51,11 @@ export const corpSecuritiesDef = defineFiberApp({
48
51
  description: "Reference to parent corporate-entity",
49
52
  immutable: true,
50
53
  },
54
+ issuerAddress: {
55
+ type: "address",
56
+ description: "State-pinned DAG address of the issuing authority (the corporation / transfer agent). Verified against proofs[].address to gate issuer-privileged transitions.",
57
+ immutable: true,
58
+ },
51
59
  shareClass: {
52
60
  type: "string",
53
61
  description: "Share class ID from corporate-entity",
@@ -70,6 +78,7 @@ export const corpSecuritiesDef = defineFiberApp({
70
78
  properties: {
71
79
  securityId: { type: "string", immutable: true },
72
80
  entityId: { type: "string", immutable: true },
81
+ issuerAddress: { type: "address", immutable: true },
73
82
  shareClass: { type: "string" },
74
83
  shareClassName: { type: "string" },
75
84
  certificateNumber: {
@@ -142,6 +151,15 @@ export const corpSecuritiesDef = defineFiberApp({
142
151
  },
143
152
  createdAt: { type: "timestamp", computed: true },
144
153
  updatedAt: { type: "timestamp", computed: true },
154
+ // Two-phase resolution gating (#24): each propose_<X> binds the executing resolution (and, for
155
+ // issuance, the parent entity) fiber via _addDependency and records the pending action here; the
156
+ // gated <X> then asserts the bound dependency state via depInState and clears the pending object.
157
+ // The dropped object-form dependencies (which the chain silently never gated) are replaced this way.
158
+ pendingIssue: { type: "object", nullable: true, computed: true },
159
+ pendingRepurchase: { type: "object", nullable: true, computed: true },
160
+ pendingReissue: { type: "object", nullable: true, computed: true },
161
+ pendingRetire: { type: "object", nullable: true, computed: true },
162
+ pendingDividend: { type: "object", nullable: true, computed: true },
145
163
  },
146
164
  },
147
165
  eventSchemas: {
@@ -167,6 +185,14 @@ export const corpSecuritiesDef = defineFiberApp({
167
185
  charterProvision: { type: "string" },
168
186
  },
169
187
  },
188
+ propose_issue: {
189
+ description: "Phase 1 of issuance (#24): bind the executing board resolution + parent entity fibers (_addDependency) and record the pending issuance",
190
+ required: ["holderId", "boardResolutionRef"],
191
+ properties: {
192
+ holderId: { type: "string" },
193
+ boardResolutionRef: { type: "string" },
194
+ },
195
+ },
170
196
  issue_shares: {
171
197
  description: "Issue shares to a holder",
172
198
  required: [
@@ -175,13 +201,16 @@ export const corpSecuritiesDef = defineFiberApp({
175
201
  "holderName",
176
202
  "issuanceDate",
177
203
  "form",
178
- "boardResolutionRef",
179
204
  "consideration",
180
205
  ],
181
206
  properties: {
182
207
  holderId: { type: "string" },
183
208
  holderType: { type: "string" },
184
209
  holderName: { type: "string" },
210
+ holderWallet: {
211
+ type: "address",
212
+ description: "DAG wallet address the holder controls; pinned so holder-initiated transfer/repurchase can be authorized via proofs[].address.",
213
+ },
185
214
  address: { type: "object" },
186
215
  issuanceDate: { type: "string", format: "date" },
187
216
  issuancePrice: { type: "number" },
@@ -190,7 +219,6 @@ export const corpSecuritiesDef = defineFiberApp({
190
219
  enum: ["CERTIFICATED", "BOOK_ENTRY", "DRS"],
191
220
  },
192
221
  certificateNumber: { type: "string" },
193
- boardResolutionRef: { type: "string" },
194
222
  consideration: { type: "object" },
195
223
  isRestricted: { type: "boolean", default: false },
196
224
  restrictionType: { type: "array" },
@@ -234,25 +262,40 @@ export const corpSecuritiesDef = defineFiberApp({
234
262
  toHolderId: { type: "string" },
235
263
  toHolderName: { type: "string" },
236
264
  toHolderType: { type: "string" },
265
+ toHolderWallet: {
266
+ type: "address",
267
+ description: "DAG wallet address the new holder controls.",
268
+ },
237
269
  toAddress: { type: "object" },
238
270
  completedDate: { type: "string", format: "date" },
239
271
  costBasis: { type: "number" },
240
272
  },
241
273
  },
274
+ propose_repurchase: {
275
+ description: "Phase 1 of repurchase (#24): bind the executing board resolution fiber (_addDependency) and record the pending repurchase",
276
+ required: ["repurchaseDate", "boardResolutionRef"],
277
+ properties: {
278
+ repurchaseDate: { type: "string", format: "date" },
279
+ boardResolutionRef: { type: "string" },
280
+ },
281
+ },
242
282
  repurchase: {
243
283
  description: "Company repurchases shares from holder",
244
- required: [
245
- "repurchaseDate",
246
- "pricePerShare",
247
- "boardResolutionRef",
248
- ],
284
+ required: ["repurchaseDate", "pricePerShare"],
249
285
  properties: {
250
286
  repurchaseDate: { type: "string", format: "date" },
251
287
  pricePerShare: { type: "number" },
252
- boardResolutionRef: { type: "string" },
253
288
  repurchaseAgreementRef: { type: "string" },
254
289
  },
255
290
  },
291
+ propose_reissue: {
292
+ description: "Phase 1 of treasury reissue (#24): bind the executing board resolution fiber (_addDependency) and record the pending reissue",
293
+ required: ["holderId", "boardResolutionRef"],
294
+ properties: {
295
+ holderId: { type: "string" },
296
+ boardResolutionRef: { type: "string" },
297
+ },
298
+ },
256
299
  reissue_from_treasury: {
257
300
  description: "Reissue treasury shares to a new holder",
258
301
  required: [
@@ -260,29 +303,34 @@ export const corpSecuritiesDef = defineFiberApp({
260
303
  "holderName",
261
304
  "holderType",
262
305
  "reissueDate",
263
- "boardResolutionRef",
264
306
  ],
265
307
  properties: {
266
308
  holderId: { type: "string" },
267
309
  holderName: { type: "string" },
268
310
  holderType: { type: "string" },
311
+ holderWallet: {
312
+ type: "address",
313
+ description: "DAG wallet address the reissued holder controls.",
314
+ },
269
315
  address: { type: "object" },
270
316
  reissueDate: { type: "string", format: "date" },
271
317
  issuancePrice: { type: "number" },
318
+ },
319
+ },
320
+ propose_retire: {
321
+ description: "Phase 1 of retirement (#24): bind the executing board resolution fiber (_addDependency) and record the pending retirement (from ISSUED or TREASURY)",
322
+ required: ["retiredDate", "boardResolutionRef"],
323
+ properties: {
324
+ retiredDate: { type: "string", format: "date" },
272
325
  boardResolutionRef: { type: "string" },
273
326
  },
274
327
  },
275
328
  retire: {
276
329
  description: "Retire shares (cancel them)",
277
- required: [
278
- "retiredDate",
279
- "retirementMethod",
280
- "boardResolutionRef",
281
- ],
330
+ required: ["retiredDate", "retirementMethod"],
282
331
  properties: {
283
332
  retiredDate: { type: "string", format: "date" },
284
333
  retirementMethod: { type: "string" },
285
- boardResolutionRef: { type: "string" },
286
334
  repurchasePrice: { type: "number" },
287
335
  },
288
336
  },
@@ -306,6 +354,14 @@ export const corpSecuritiesDef = defineFiberApp({
306
354
  newShareCount: { type: "integer" },
307
355
  },
308
356
  },
357
+ propose_dividend: {
358
+ description: "Phase 1 of dividend declaration (#24): bind the executing board resolution fiber (_addDependency) and record the pending declaration",
359
+ required: ["actionId", "resolutionRef"],
360
+ properties: {
361
+ actionId: { type: "string" },
362
+ resolutionRef: { type: "string" },
363
+ },
364
+ },
309
365
  declare_dividend: {
310
366
  description: "Record dividend declaration affecting this lot (for stock dividends)",
311
367
  required: [
@@ -313,7 +369,6 @@ export const corpSecuritiesDef = defineFiberApp({
313
369
  "dividendType",
314
370
  "recordDate",
315
371
  "paymentDate",
316
- "resolutionRef",
317
372
  ],
318
373
  properties: {
319
374
  actionId: { type: "string" },
@@ -322,7 +377,6 @@ export const corpSecuritiesDef = defineFiberApp({
322
377
  paymentDate: { type: "string", format: "date" },
323
378
  cashAmount: { type: "number" },
324
379
  stockShares: { type: "integer" },
325
- resolutionRef: { type: "string" },
326
380
  },
327
381
  },
328
382
  remove_restriction: {
@@ -348,6 +402,11 @@ export const corpSecuritiesDef = defineFiberApp({
348
402
  },
349
403
  name: { type: "string" },
350
404
  taxId: { type: "string", nullable: true },
405
+ walletAddress: {
406
+ type: "address",
407
+ nullable: true,
408
+ description: "State-pinned DAG wallet address controlled by this holder; verified against proofs[].address to gate holder-initiated transfer/repurchase.",
409
+ },
351
410
  address: { type: "object", nullable: true },
352
411
  acquisitionDate: { type: "string", format: "date" },
353
412
  acquisitionMethod: {
@@ -544,7 +603,8 @@ export const corpSecuritiesDef = defineFiberApp({
544
603
  from: "AUTHORIZED",
545
604
  to: "AUTHORIZED",
546
605
  eventName: "authorize_shares",
547
- guard: { "==": [1, 1] },
606
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
607
+ guard: signerIsParty("state.issuerAddress"),
548
608
  effect: {
549
609
  merge: [
550
610
  { var: "state" },
@@ -566,24 +626,53 @@ export const corpSecuritiesDef = defineFiberApp({
566
626
  ],
567
627
  },
568
628
  },
569
- // AUTHORIZED -> ISSUED
629
+ // AUTHORIZED -> AUTHORIZED (propose_issue) — phase 1 (#24): bind the executing resolution + parent
630
+ // entity fibers and record the pending issuance, so issue_shares can read their state next transition.
631
+ {
632
+ from: "AUTHORIZED",
633
+ to: "AUTHORIZED",
634
+ eventName: "propose_issue",
635
+ // authority gate — an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
636
+ guard: signerIsParty("state.issuerAddress"),
637
+ effect: {
638
+ merge: [
639
+ { var: "state" },
640
+ {
641
+ pendingIssue: {
642
+ holderId: { var: "event.holderId" },
643
+ ref: { var: "event.boardResolutionRef" },
644
+ proposedAt: { var: "$ordinal" },
645
+ },
646
+ },
647
+ // bind the resolution fiber so issue_shares can assert its state next transition
648
+ addDependency({ var: "event.boardResolutionRef" }),
649
+ // bind the parent entity fiber so issue_shares can assert it is ACTIVE
650
+ addDependency({ var: "state.entityId" }),
651
+ ],
652
+ },
653
+ dependencies: [],
654
+ },
655
+ // AUTHORIZED -> ISSUED — phase 2 (#24): issue once the bound resolution is EXECUTED and the parent
656
+ // entity is ACTIVE. depInState replaces the dropped object-form dependencies (which never gated).
570
657
  {
571
658
  from: "AUTHORIZED",
572
659
  to: "ISSUED",
573
660
  eventName: "issue_shares",
574
- guard: { "==": [1, 1] },
575
- dependencies: [
576
- {
577
- machine: "corporate-resolution",
578
- instanceRef: { var: "event.boardResolutionRef" },
579
- requiredState: "EXECUTED",
580
- },
581
- {
582
- machine: "corporate-entity",
583
- instanceRef: { var: "state.entityId" },
584
- requiredState: "ACTIVE",
585
- },
586
- ],
661
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
662
+ guard: {
663
+ and: [
664
+ signerIsParty("state.issuerAddress"),
665
+ // the proposal must target this holder, and its bound resolution must be EXECUTED
666
+ {
667
+ "==": [
668
+ { var: "state.pendingIssue.holderId" },
669
+ { var: "event.holderId" },
670
+ ],
671
+ },
672
+ depInState("state.pendingIssue.ref", "EXECUTED"),
673
+ depInState("state.entityId", "ACTIVE"),
674
+ ],
675
+ },
587
676
  effect: {
588
677
  merge: [
589
678
  { var: "state" },
@@ -597,6 +686,7 @@ export const corpSecuritiesDef = defineFiberApp({
597
686
  holderId: { var: "event.holderId" },
598
687
  holderType: { var: "event.holderType" },
599
688
  name: { var: "event.holderName" },
689
+ walletAddress: { var: "event.holderWallet" },
600
690
  address: { var: "event.address" },
601
691
  acquisitionDate: { var: "event.issuanceDate" },
602
692
  acquisitionMethod: "ORIGINAL_ISSUANCE",
@@ -613,15 +703,22 @@ export const corpSecuritiesDef = defineFiberApp({
613
703
  legends: { var: "event.legends" },
614
704
  },
615
705
  issuanceDetails: {
616
- boardResolutionRef: { var: "event.boardResolutionRef" },
706
+ boardResolutionRef: { var: "state.pendingIssue.ref" },
617
707
  consideration: { var: "event.consideration" },
618
708
  exemptionUsed: { var: "event.exemptionUsed" },
619
709
  accreditedInvestor: { var: "event.accreditedInvestor" },
620
710
  },
711
+ // clear the consumed proposal
712
+ pendingIssue: null,
713
+ },
714
+ {
715
+ _emit: [
716
+ { name: "SHARES_ISSUED", data: { var: "event" }, destination: "external" },
717
+ ],
621
718
  },
622
719
  ],
623
720
  },
624
- emits: ["SHARES_ISSUED"],
721
+ dependencies: [],
625
722
  },
626
723
  // ISSUED -> TRANSFERRED
627
724
  {
@@ -630,6 +727,8 @@ export const corpSecuritiesDef = defineFiberApp({
630
727
  eventName: "initiate_transfer",
631
728
  guard: {
632
729
  and: [
730
+ // authority gate — an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
731
+ signerIsParty("state.holder.walletAddress"),
633
732
  {
634
733
  or: [
635
734
  { "==": [{ var: "state.restrictions.isRestricted" }, false] },
@@ -638,7 +737,7 @@ export const corpSecuritiesDef = defineFiberApp({
638
737
  },
639
738
  {
640
739
  ">=": [
641
- { var: "$timestamp" },
740
+ { var: "$ordinal" },
642
741
  { var: "state.restrictions.restrictionEndDate" },
643
742
  ],
644
743
  },
@@ -653,7 +752,7 @@ export const corpSecuritiesDef = defineFiberApp({
653
752
  {
654
753
  status: "TRANSFERRED",
655
754
  transferHistory: {
656
- cat: [
755
+ merge: [
657
756
  { var: "state.transferHistory" },
658
757
  [
659
758
  {
@@ -669,16 +768,21 @@ export const corpSecuritiesDef = defineFiberApp({
669
768
  ],
670
769
  },
671
770
  },
771
+ {
772
+ _emit: [
773
+ { name: "TRANSFER_INITIATED", data: { var: "event" }, destination: "external" },
774
+ ],
775
+ },
672
776
  ],
673
777
  },
674
- emits: ["TRANSFER_INITIATED"],
675
778
  },
676
779
  // TRANSFERRED -> ISSUED
677
780
  {
678
781
  from: "TRANSFERRED",
679
782
  to: "ISSUED",
680
783
  eventName: "complete_transfer",
681
- guard: { "==": [1, 1] },
784
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
785
+ guard: signerIsParty("state.issuerAddress"),
682
786
  effect: {
683
787
  merge: [
684
788
  { var: "state" },
@@ -688,6 +792,7 @@ export const corpSecuritiesDef = defineFiberApp({
688
792
  holderId: { var: "event.toHolderId" },
689
793
  holderType: { var: "event.toHolderType" },
690
794
  name: { var: "event.toHolderName" },
795
+ walletAddress: { var: "event.toHolderWallet" },
691
796
  address: { var: "event.toAddress" },
692
797
  acquisitionDate: { var: "event.completedDate" },
693
798
  acquisitionMethod: "PURCHASE",
@@ -701,30 +806,64 @@ export const corpSecuritiesDef = defineFiberApp({
701
806
  ],
702
807
  },
703
808
  },
809
+ {
810
+ _emit: [
811
+ { name: "TRANSFER_COMPLETED", data: { var: "event" }, destination: "external" },
812
+ ],
813
+ },
814
+ ],
815
+ },
816
+ },
817
+ // ISSUED -> ISSUED (propose_repurchase) — phase 1 (#24): bind the executing resolution fiber and
818
+ // record the pending repurchase, so repurchase can read the resolution's state next transition.
819
+ {
820
+ from: "ISSUED",
821
+ to: "ISSUED",
822
+ eventName: "propose_repurchase",
823
+ // authority gate — the selling holder must sign; an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
824
+ guard: signerIsParty("state.holder.walletAddress"),
825
+ effect: {
826
+ merge: [
827
+ { var: "state" },
828
+ {
829
+ pendingRepurchase: {
830
+ repurchaseDate: { var: "event.repurchaseDate" },
831
+ ref: { var: "event.boardResolutionRef" },
832
+ proposedAt: { var: "$ordinal" },
833
+ },
834
+ },
835
+ // bind the resolution fiber so repurchase can assert its state next transition
836
+ addDependency({ var: "event.boardResolutionRef" }),
704
837
  ],
705
838
  },
706
- emits: ["TRANSFER_COMPLETED"],
839
+ dependencies: [],
707
840
  },
708
- // ISSUED -> TREASURY
841
+ // ISSUED -> TREASURY — phase 2 (#24): repurchase once the bound resolution is EXECUTED.
709
842
  {
710
843
  from: "ISSUED",
711
844
  to: "TREASURY",
712
845
  eventName: "repurchase",
713
- guard: { "==": [1, 1] },
714
- dependencies: [
715
- {
716
- machine: "corporate-resolution",
717
- instanceRef: { var: "event.boardResolutionRef" },
718
- requiredState: "EXECUTED",
719
- },
720
- ],
846
+ // authority gate the selling holder must sign; an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
847
+ guard: {
848
+ and: [
849
+ signerIsParty("state.holder.walletAddress"),
850
+ // the proposal must match this repurchase, and its bound resolution must be EXECUTED
851
+ {
852
+ "==": [
853
+ { var: "state.pendingRepurchase.repurchaseDate" },
854
+ { var: "event.repurchaseDate" },
855
+ ],
856
+ },
857
+ depInState("state.pendingRepurchase.ref", "EXECUTED"),
858
+ ],
859
+ },
721
860
  effect: {
722
861
  merge: [
723
862
  { var: "state" },
724
863
  {
725
864
  status: "TREASURY",
726
865
  transferHistory: {
727
- cat: [
866
+ merge: [
728
867
  { var: "state.transferHistory" },
729
868
  [
730
869
  {
@@ -754,24 +893,61 @@ export const corpSecuritiesDef = defineFiberApp({
754
893
  ],
755
894
  },
756
895
  },
896
+ // clear the consumed proposal
897
+ pendingRepurchase: null,
898
+ },
899
+ {
900
+ _emit: [
901
+ { name: "SHARES_REPURCHASED", data: { var: "event" }, destination: "external" },
902
+ ],
757
903
  },
758
904
  ],
759
905
  },
760
- emits: ["SHARES_REPURCHASED"],
906
+ dependencies: [],
761
907
  },
762
- // TREASURY -> ISSUED
908
+ // TREASURY -> TREASURY (propose_reissue) — phase 1 (#24): bind the executing resolution fiber and
909
+ // record the pending reissue, so reissue_from_treasury can read the resolution's state next transition.
910
+ {
911
+ from: "TREASURY",
912
+ to: "TREASURY",
913
+ eventName: "propose_reissue",
914
+ // authority gate — an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
915
+ guard: signerIsParty("state.issuerAddress"),
916
+ effect: {
917
+ merge: [
918
+ { var: "state" },
919
+ {
920
+ pendingReissue: {
921
+ holderId: { var: "event.holderId" },
922
+ ref: { var: "event.boardResolutionRef" },
923
+ proposedAt: { var: "$ordinal" },
924
+ },
925
+ },
926
+ // bind the resolution fiber so reissue_from_treasury can assert its state next transition
927
+ addDependency({ var: "event.boardResolutionRef" }),
928
+ ],
929
+ },
930
+ dependencies: [],
931
+ },
932
+ // TREASURY -> ISSUED — phase 2 (#24): reissue once the bound resolution is EXECUTED.
763
933
  {
764
934
  from: "TREASURY",
765
935
  to: "ISSUED",
766
936
  eventName: "reissue_from_treasury",
767
- guard: { "==": [1, 1] },
768
- dependencies: [
769
- {
770
- machine: "corporate-resolution",
771
- instanceRef: { var: "event.boardResolutionRef" },
772
- requiredState: "EXECUTED",
773
- },
774
- ],
937
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
938
+ guard: {
939
+ and: [
940
+ signerIsParty("state.issuerAddress"),
941
+ // the proposal must target this holder, and its bound resolution must be EXECUTED
942
+ {
943
+ "==": [
944
+ { var: "state.pendingReissue.holderId" },
945
+ { var: "event.holderId" },
946
+ ],
947
+ },
948
+ depInState("state.pendingReissue.ref", "EXECUTED"),
949
+ ],
950
+ },
775
951
  effect: {
776
952
  merge: [
777
953
  { var: "state" },
@@ -781,6 +957,7 @@ export const corpSecuritiesDef = defineFiberApp({
781
957
  holderId: { var: "event.holderId" },
782
958
  holderType: { var: "event.holderType" },
783
959
  name: { var: "event.holderName" },
960
+ walletAddress: { var: "event.holderWallet" },
784
961
  address: { var: "event.address" },
785
962
  acquisitionDate: { var: "event.reissueDate" },
786
963
  acquisitionMethod: "PURCHASE",
@@ -791,24 +968,85 @@ export const corpSecuritiesDef = defineFiberApp({
791
968
  ],
792
969
  },
793
970
  },
971
+ // clear the consumed proposal
972
+ pendingReissue: null,
973
+ },
974
+ {
975
+ _emit: [
976
+ { name: "TREASURY_SHARES_REISSUED", data: { var: "event" }, destination: "external" },
977
+ ],
978
+ },
979
+ ],
980
+ },
981
+ dependencies: [],
982
+ },
983
+ // ISSUED -> ISSUED (propose_retire) — phase 1 (#24): bind the executing resolution fiber and record
984
+ // the pending retirement, so the retire transition can read the resolution's state next transition.
985
+ {
986
+ from: "ISSUED",
987
+ to: "ISSUED",
988
+ eventName: "propose_retire",
989
+ // authority gate — an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
990
+ guard: signerIsParty("state.issuerAddress"),
991
+ effect: {
992
+ merge: [
993
+ { var: "state" },
994
+ {
995
+ pendingRetire: {
996
+ retiredDate: { var: "event.retiredDate" },
997
+ ref: { var: "event.boardResolutionRef" },
998
+ proposedAt: { var: "$ordinal" },
999
+ },
1000
+ },
1001
+ // bind the resolution fiber so retire can assert its state next transition
1002
+ addDependency({ var: "event.boardResolutionRef" }),
1003
+ ],
1004
+ },
1005
+ dependencies: [],
1006
+ },
1007
+ // TREASURY -> TREASURY (propose_retire) — phase 1 (#24): the treasury-side counterpart, binding the
1008
+ // executing resolution fiber and recording the pending retirement before retire executes.
1009
+ {
1010
+ from: "TREASURY",
1011
+ to: "TREASURY",
1012
+ eventName: "propose_retire",
1013
+ // authority gate — an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
1014
+ guard: signerIsParty("state.issuerAddress"),
1015
+ effect: {
1016
+ merge: [
1017
+ { var: "state" },
1018
+ {
1019
+ pendingRetire: {
1020
+ retiredDate: { var: "event.retiredDate" },
1021
+ ref: { var: "event.boardResolutionRef" },
1022
+ proposedAt: { var: "$ordinal" },
1023
+ },
794
1024
  },
1025
+ // bind the resolution fiber so retire can assert its state next transition
1026
+ addDependency({ var: "event.boardResolutionRef" }),
795
1027
  ],
796
1028
  },
797
- emits: ["TREASURY_SHARES_REISSUED"],
1029
+ dependencies: [],
798
1030
  },
799
- // ISSUED -> RETIRED
1031
+ // ISSUED -> RETIRED — phase 2 (#24): retire once the bound resolution is EXECUTED.
800
1032
  {
801
1033
  from: "ISSUED",
802
1034
  to: "RETIRED",
803
1035
  eventName: "retire",
804
- guard: { "==": [1, 1] },
805
- dependencies: [
806
- {
807
- machine: "corporate-resolution",
808
- instanceRef: { var: "event.boardResolutionRef" },
809
- requiredState: "EXECUTED",
810
- },
811
- ],
1036
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
1037
+ guard: {
1038
+ and: [
1039
+ signerIsParty("state.issuerAddress"),
1040
+ // the proposal must match this retirement, and its bound resolution must be EXECUTED
1041
+ {
1042
+ "==": [
1043
+ { var: "state.pendingRetire.retiredDate" },
1044
+ { var: "event.retiredDate" },
1045
+ ],
1046
+ },
1047
+ depInState("state.pendingRetire.ref", "EXECUTED"),
1048
+ ],
1049
+ },
812
1050
  effect: {
813
1051
  merge: [
814
1052
  { var: "state" },
@@ -818,27 +1056,40 @@ export const corpSecuritiesDef = defineFiberApp({
818
1056
  retiredDate: { var: "event.retiredDate" },
819
1057
  retirementMethod: { var: "event.retirementMethod" },
820
1058
  repurchasePrice: { var: "event.repurchasePrice" },
821
- boardResolutionRef: { var: "event.boardResolutionRef" },
1059
+ boardResolutionRef: { var: "state.pendingRetire.ref" },
822
1060
  },
823
1061
  holder: null,
1062
+ // clear the consumed proposal
1063
+ pendingRetire: null,
1064
+ },
1065
+ {
1066
+ _emit: [
1067
+ { name: "SHARES_RETIRED", data: { var: "event" }, destination: "external" },
1068
+ ],
824
1069
  },
825
1070
  ],
826
1071
  },
827
- emits: ["SHARES_RETIRED"],
1072
+ dependencies: [],
828
1073
  },
829
- // TREASURY -> RETIRED
1074
+ // TREASURY -> RETIRED — phase 2 (#24): retire once the bound resolution is EXECUTED.
830
1075
  {
831
1076
  from: "TREASURY",
832
1077
  to: "RETIRED",
833
1078
  eventName: "retire",
834
- guard: { "==": [1, 1] },
835
- dependencies: [
836
- {
837
- machine: "corporate-resolution",
838
- instanceRef: { var: "event.boardResolutionRef" },
839
- requiredState: "EXECUTED",
840
- },
841
- ],
1079
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
1080
+ guard: {
1081
+ and: [
1082
+ signerIsParty("state.issuerAddress"),
1083
+ // the proposal must match this retirement, and its bound resolution must be EXECUTED
1084
+ {
1085
+ "==": [
1086
+ { var: "state.pendingRetire.retiredDate" },
1087
+ { var: "event.retiredDate" },
1088
+ ],
1089
+ },
1090
+ depInState("state.pendingRetire.ref", "EXECUTED"),
1091
+ ],
1092
+ },
842
1093
  effect: {
843
1094
  merge: [
844
1095
  { var: "state" },
@@ -848,26 +1099,34 @@ export const corpSecuritiesDef = defineFiberApp({
848
1099
  retiredDate: { var: "event.retiredDate" },
849
1100
  retirementMethod: { var: "event.retirementMethod" },
850
1101
  repurchasePrice: { var: "event.repurchasePrice" },
851
- boardResolutionRef: { var: "event.boardResolutionRef" },
1102
+ boardResolutionRef: { var: "state.pendingRetire.ref" },
852
1103
  },
853
1104
  holder: null,
1105
+ // clear the consumed proposal
1106
+ pendingRetire: null,
1107
+ },
1108
+ {
1109
+ _emit: [
1110
+ { name: "SHARES_RETIRED", data: { var: "event" }, destination: "external" },
1111
+ ],
854
1112
  },
855
1113
  ],
856
1114
  },
857
- emits: ["SHARES_RETIRED"],
1115
+ dependencies: [],
858
1116
  },
859
1117
  // ISSUED -> ISSUED (stock_split)
860
1118
  {
861
1119
  from: "ISSUED",
862
1120
  to: "ISSUED",
863
1121
  eventName: "stock_split",
864
- guard: { "==": [1, 1] },
1122
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
1123
+ guard: signerIsParty("state.issuerAddress"),
865
1124
  effect: {
866
1125
  merge: [
867
1126
  { var: "state" },
868
1127
  {
869
1128
  corporateActions: {
870
- cat: [
1129
+ merge: [
871
1130
  { var: "state.corporateActions" },
872
1131
  [
873
1132
  {
@@ -884,23 +1143,58 @@ export const corpSecuritiesDef = defineFiberApp({
884
1143
  },
885
1144
  shareCount: { var: "event.newShareCount" },
886
1145
  },
1146
+ {
1147
+ _emit: [
1148
+ { name: "STOCK_SPLIT_APPLIED", data: { var: "event" }, destination: "external" },
1149
+ ],
1150
+ },
887
1151
  ],
888
1152
  },
889
- emits: ["STOCK_SPLIT_APPLIED"],
890
1153
  },
891
- // ISSUED -> ISSUED (declare_dividend) - stock dividend handling
1154
+ // ISSUED -> ISSUED (propose_dividend) phase 1 (#24): bind the executing resolution fiber and record
1155
+ // the pending declaration, so declare_dividend can read the resolution's state next transition.
1156
+ {
1157
+ from: "ISSUED",
1158
+ to: "ISSUED",
1159
+ eventName: "propose_dividend",
1160
+ // authority gate — an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
1161
+ guard: signerIsParty("state.issuerAddress"),
1162
+ effect: {
1163
+ merge: [
1164
+ { var: "state" },
1165
+ {
1166
+ pendingDividend: {
1167
+ actionId: { var: "event.actionId" },
1168
+ ref: { var: "event.resolutionRef" },
1169
+ proposedAt: { var: "$ordinal" },
1170
+ },
1171
+ },
1172
+ // bind the resolution fiber so declare_dividend can assert its state next transition
1173
+ addDependency({ var: "event.resolutionRef" }),
1174
+ ],
1175
+ },
1176
+ dependencies: [],
1177
+ },
1178
+ // ISSUED -> ISSUED (declare_dividend) — phase 2 (#24): stock dividend handling once the bound
1179
+ // resolution is EXECUTED.
892
1180
  {
893
1181
  from: "ISSUED",
894
1182
  to: "ISSUED",
895
1183
  eventName: "declare_dividend",
896
- guard: { "==": [1, 1] },
897
- dependencies: [
898
- {
899
- machine: "corporate-resolution",
900
- instanceRef: { var: "event.resolutionRef" },
901
- requiredState: "EXECUTED",
902
- },
903
- ],
1184
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
1185
+ guard: {
1186
+ and: [
1187
+ signerIsParty("state.issuerAddress"),
1188
+ // the proposal must target this action, and its bound resolution must be EXECUTED
1189
+ {
1190
+ "==": [
1191
+ { var: "state.pendingDividend.actionId" },
1192
+ { var: "event.actionId" },
1193
+ ],
1194
+ },
1195
+ depInState("state.pendingDividend.ref", "EXECUTED"),
1196
+ ],
1197
+ },
904
1198
  effect: {
905
1199
  if: [
906
1200
  { "==": [{ var: "event.dividendType" }, "STOCK"] },
@@ -909,7 +1203,7 @@ export const corpSecuritiesDef = defineFiberApp({
909
1203
  { var: "state" },
910
1204
  {
911
1205
  corporateActions: {
912
- cat: [
1206
+ merge: [
913
1207
  { var: "state.corporateActions" },
914
1208
  [
915
1209
  {
@@ -923,7 +1217,7 @@ export const corpSecuritiesDef = defineFiberApp({
923
1217
  { var: "event.stockShares" },
924
1218
  ],
925
1219
  },
926
- resolutionRef: { var: "event.resolutionRef" },
1220
+ resolutionRef: { var: "state.pendingDividend.ref" },
927
1221
  },
928
1222
  ],
929
1223
  ],
@@ -934,19 +1228,29 @@ export const corpSecuritiesDef = defineFiberApp({
934
1228
  { var: "event.stockShares" },
935
1229
  ],
936
1230
  },
1231
+ // clear the consumed proposal
1232
+ pendingDividend: null,
937
1233
  },
938
1234
  ],
939
1235
  },
940
- { var: "state" },
1236
+ {
1237
+ merge: [
1238
+ { var: "state" },
1239
+ // cash dividend: no share change, but still clear the consumed proposal
1240
+ { pendingDividend: null },
1241
+ ],
1242
+ },
941
1243
  ],
942
1244
  },
1245
+ dependencies: [],
943
1246
  },
944
1247
  // ISSUED -> ISSUED (remove_restriction)
945
1248
  {
946
1249
  from: "ISSUED",
947
1250
  to: "ISSUED",
948
1251
  eventName: "remove_restriction",
949
- guard: { "==": [1, 1] },
1252
+ // authority gate an identity role attestation (ISSUER/BOARD_MEMBER/...) layers on additively when the identity registry lands (docs/design/app-hardening-identity-integration.md §4.2)
1253
+ guard: signerIsParty("state.issuerAddress"),
950
1254
  effect: {
951
1255
  merge: [
952
1256
  { var: "state" },
@@ -987,9 +1291,13 @@ export const corpSecuritiesDef = defineFiberApp({
987
1291
  ],
988
1292
  },
989
1293
  },
1294
+ {
1295
+ _emit: [
1296
+ { name: "RESTRICTION_REMOVED", data: { var: "event" }, destination: "external" },
1297
+ ],
1298
+ },
990
1299
  ],
991
1300
  },
992
- emits: ["RESTRICTION_REMOVED"],
993
1301
  },
994
1302
  ],
995
1303
  });