@hyperscale0/hsx 2.4.0 → 3.0.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 (249) hide show
  1. package/CHANGELOG.md +2 -400
  2. package/README.md +3 -92
  3. package/dist/src/ast.d.ts +99 -310
  4. package/dist/src/ast.d.ts.map +1 -1
  5. package/dist/src/ast.js +16 -69
  6. package/dist/src/ast.js.map +1 -1
  7. package/dist/src/cli.d.ts +6 -19
  8. package/dist/src/cli.d.ts.map +1 -1
  9. package/dist/src/cli.js +76 -315
  10. package/dist/src/cli.js.map +1 -1
  11. package/dist/src/compile.d.ts +23 -73
  12. package/dist/src/compile.d.ts.map +1 -1
  13. package/dist/src/compile.js +1113 -148
  14. package/dist/src/compile.js.map +1 -1
  15. package/dist/src/cost.d.ts +8 -77
  16. package/dist/src/cost.d.ts.map +1 -1
  17. package/dist/src/cost.js +13 -422
  18. package/dist/src/cost.js.map +1 -1
  19. package/dist/src/format.d.ts +8 -7
  20. package/dist/src/format.d.ts.map +1 -1
  21. package/dist/src/format.js +9 -175
  22. package/dist/src/format.js.map +1 -1
  23. package/dist/src/headers.d.ts +35 -0
  24. package/dist/src/headers.d.ts.map +1 -0
  25. package/dist/src/headers.js +108 -0
  26. package/dist/src/headers.js.map +1 -0
  27. package/dist/src/index.d.ts +6 -12
  28. package/dist/src/index.d.ts.map +1 -1
  29. package/dist/src/index.js +4 -9
  30. package/dist/src/index.js.map +1 -1
  31. package/dist/src/lex.d.ts +8 -28
  32. package/dist/src/lex.d.ts.map +1 -1
  33. package/dist/src/lex.js +88 -146
  34. package/dist/src/lex.js.map +1 -1
  35. package/dist/src/parse.d.ts +4 -17
  36. package/dist/src/parse.d.ts.map +1 -1
  37. package/dist/src/parse.js +402 -1040
  38. package/dist/src/parse.js.map +1 -1
  39. package/dist/src/std-bundle.d.ts.map +1 -1
  40. package/dist/src/std-bundle.js +12 -20
  41. package/dist/src/std-bundle.js.map +1 -1
  42. package/dist/src/std-library.d.ts +1 -1
  43. package/dist/src/std-library.d.ts.map +1 -1
  44. package/dist/src/std-library.js +1 -5
  45. package/dist/src/std-library.js.map +1 -1
  46. package/dist/src/tunables.d.ts +7 -0
  47. package/dist/src/tunables.d.ts.map +1 -0
  48. package/dist/src/tunables.js +26 -0
  49. package/dist/src/tunables.js.map +1 -0
  50. package/dist/src/version.d.ts +2 -4
  51. package/dist/src/version.d.ts.map +1 -1
  52. package/dist/src/version.js +2 -4
  53. package/dist/src/version.js.map +1 -1
  54. package/docs/README.md +179 -41
  55. package/docs/headers.md +44 -0
  56. package/examples/cost-table.json +99 -751
  57. package/examples/library.hsx +59 -0
  58. package/package.json +9 -17
  59. package/src/ast.ts +82 -441
  60. package/src/cli.ts +77 -362
  61. package/src/compile.ts +1535 -247
  62. package/src/cost.ts +28 -671
  63. package/src/format.ts +12 -256
  64. package/src/headers.ts +126 -0
  65. package/src/index.ts +7 -39
  66. package/src/lex.ts +99 -195
  67. package/src/parse.ts +403 -1209
  68. package/src/std-bundle.ts +12 -20
  69. package/src/std-library.ts +2 -7
  70. package/src/tunables.ts +31 -0
  71. package/src/version.ts +2 -5
  72. package/std/approvals.hsx +17 -0
  73. package/std/cards.hsx +63 -0
  74. package/std/collections.hsx +31 -0
  75. package/std/escrow.hsx +43 -0
  76. package/std/financing.hsx +372 -0
  77. package/std/insurance.hsx +59 -0
  78. package/std/lending.hsx +115 -0
  79. package/std/marketplace.hsx +24 -0
  80. package/std/money.hsx +195 -0
  81. package/std/savings.hsx +44 -0
  82. package/std/travel.hsx +98 -0
  83. package/std/wallet.hsx +41 -0
  84. package/dist/src/diagnostics.d.ts +0 -13
  85. package/dist/src/diagnostics.d.ts.map +0 -1
  86. package/dist/src/diagnostics.js +0 -587
  87. package/dist/src/diagnostics.js.map +0 -1
  88. package/dist/src/emit.d.ts +0 -51
  89. package/dist/src/emit.d.ts.map +0 -1
  90. package/dist/src/emit.js +0 -192
  91. package/dist/src/emit.js.map +0 -1
  92. package/dist/src/entry-overrides.d.ts +0 -58
  93. package/dist/src/entry-overrides.d.ts.map +0 -1
  94. package/dist/src/entry-overrides.js +0 -284
  95. package/dist/src/entry-overrides.js.map +0 -1
  96. package/dist/src/ir.d.ts +0 -73
  97. package/dist/src/ir.d.ts.map +0 -1
  98. package/dist/src/ir.js +0 -15
  99. package/dist/src/ir.js.map +0 -1
  100. package/dist/src/limits.d.ts +0 -23
  101. package/dist/src/limits.d.ts.map +0 -1
  102. package/dist/src/limits.js +0 -23
  103. package/dist/src/limits.js.map +0 -1
  104. package/dist/src/lsp/server.d.ts +0 -32
  105. package/dist/src/lsp/server.d.ts.map +0 -1
  106. package/dist/src/lsp/server.js +0 -391
  107. package/dist/src/lsp/server.js.map +0 -1
  108. package/dist/src/modules.d.ts +0 -38
  109. package/dist/src/modules.d.ts.map +0 -1
  110. package/dist/src/modules.js +0 -372
  111. package/dist/src/modules.js.map +0 -1
  112. package/dist/src/typecheck.d.ts +0 -8
  113. package/dist/src/typecheck.d.ts.map +0 -1
  114. package/dist/src/typecheck.js +0 -4131
  115. package/dist/src/typecheck.js.map +0 -1
  116. package/docs/guide/01-first-program.md +0 -24
  117. package/docs/guide/02-money.md +0 -25
  118. package/docs/guide/03-instruments.md +0 -93
  119. package/docs/guide/04-lifecycles.md +0 -40
  120. package/docs/guide/05-fees-and-splits.md +0 -45
  121. package/docs/guide/06-schedules.md +0 -26
  122. package/docs/guide/07-composition.md +0 -52
  123. package/docs/guide/08-writing-a-module.md +0 -85
  124. package/docs/guide/09-cost.md +0 -24
  125. package/docs/guide/10-diagnostics.md +0 -27
  126. package/docs/llms-full.txt +0 -3684
  127. package/docs/llms.txt +0 -44
  128. package/docs/piece-plans.md +0 -120
  129. package/docs/playground.md +0 -55
  130. package/docs/reference/cli.md +0 -36
  131. package/docs/reference/diagnostics.md +0 -901
  132. package/docs/reference/grammar.md +0 -38
  133. package/docs/reference/std/advance.md +0 -112
  134. package/docs/reference/std/cancellable_booking.md +0 -159
  135. package/docs/reference/std/captured_payment.md +0 -115
  136. package/docs/reference/std/conditional_disbursement.md +0 -101
  137. package/docs/reference/std/credit_facility.md +0 -108
  138. package/docs/reference/std/held_payment.md +0 -173
  139. package/docs/reference/std/instant_transfer.md +0 -97
  140. package/docs/reference/std/metered.md +0 -89
  141. package/docs/reference/std/pooled_split.md +0 -95
  142. package/docs/reference/std/premium_forward.md +0 -119
  143. package/docs/reference/std/reconciled_payout.md +0 -103
  144. package/docs/reference/std/rotating_pool.md +0 -130
  145. package/docs/reference/std/scheduled.md +0 -136
  146. package/docs/reference/std/security_deposit.md +0 -138
  147. package/docs/reference/std/settlement_batch.md +0 -123
  148. package/docs/reference/std/swap.md +0 -133
  149. package/docs/reference/std/threshold_pool.md +0 -138
  150. package/docs/reference/std/weighted_distribution.md +0 -135
  151. package/docs/reference/types.md +0 -61
  152. package/docs/reference/udl-output.md +0 -13
  153. package/examples/01-first-program/README.md +0 -45
  154. package/examples/01-first-program/tip-jar.hsx +0 -17
  155. package/examples/02-imports-and-modules/README.md +0 -96
  156. package/examples/02-imports-and-modules/photo-booth.hsx +0 -37
  157. package/examples/03-diagnostics/README.md +0 -68
  158. package/examples/03-diagnostics/corner-shop-fixed.hsx +0 -22
  159. package/examples/03-diagnostics/corner-shop.hsx +0 -19
  160. package/examples/04-complete-product/README.md +0 -84
  161. package/examples/04-complete-product/study-hall.hsx +0 -67
  162. package/examples/05-authored-instrument/README.md +0 -5
  163. package/examples/05-authored-instrument/payment.hsx +0 -37
  164. package/examples/05-watch-club/README.md +0 -6
  165. package/examples/05-watch-club/watch-club.hsx +0 -123
  166. package/examples/README.md +0 -48
  167. package/examples/advance/README.md +0 -3
  168. package/examples/advance/advance.hsx +0 -13
  169. package/examples/advance/advance.udl +0 -367
  170. package/examples/cancellable_booking/README.md +0 -3
  171. package/examples/cancellable_booking/cancellable_booking.hsx +0 -14
  172. package/examples/cancellable_booking/cancellable_booking.udl +0 -413
  173. package/examples/captured_payment/README.md +0 -3
  174. package/examples/captured_payment/captured_payment.hsx +0 -17
  175. package/examples/captured_payment/captured_payment.udl +0 -686
  176. package/examples/conditional_disbursement/README.md +0 -3
  177. package/examples/conditional_disbursement/conditional_disbursement.hsx +0 -15
  178. package/examples/conditional_disbursement/conditional_disbursement.udl +0 -418
  179. package/examples/credit_facility/README.md +0 -3
  180. package/examples/credit_facility/credit_facility.hsx +0 -24
  181. package/examples/credit_facility/credit_facility.udl +0 -1396
  182. package/examples/held_payment/README.md +0 -3
  183. package/examples/held_payment/held_payment.hsx +0 -13
  184. package/examples/held_payment/held_payment.udl +0 -569
  185. package/examples/instant_transfer/README.md +0 -3
  186. package/examples/instant_transfer/instant_transfer.hsx +0 -16
  187. package/examples/instant_transfer/instant_transfer.udl +0 -376
  188. package/examples/metered/README.md +0 -3
  189. package/examples/metered/metered.hsx +0 -13
  190. package/examples/metered/metered.udl +0 -253
  191. package/examples/pooled_split/README.md +0 -3
  192. package/examples/pooled_split/pooled_split.hsx +0 -15
  193. package/examples/pooled_split/pooled_split.udl +0 -432
  194. package/examples/premium_forward/README.md +0 -3
  195. package/examples/premium_forward/premium_forward.hsx +0 -19
  196. package/examples/premium_forward/premium_forward.udl +0 -604
  197. package/examples/reconciled_payout/README.md +0 -3
  198. package/examples/reconciled_payout/reconciled_payout.hsx +0 -13
  199. package/examples/reconciled_payout/reconciled_payout.udl +0 -312
  200. package/examples/rotating_pool/README.md +0 -3
  201. package/examples/rotating_pool/rotating_pool.hsx +0 -18
  202. package/examples/rotating_pool/rotating_pool.udl +0 -4370
  203. package/examples/scheduled/README.md +0 -3
  204. package/examples/scheduled/scheduled.hsx +0 -12
  205. package/examples/scheduled/scheduled.udl +0 -355
  206. package/examples/security_deposit/README.md +0 -3
  207. package/examples/security_deposit/security_deposit.hsx +0 -21
  208. package/examples/security_deposit/security_deposit.udl +0 -320
  209. package/examples/settlement_batch/README.md +0 -3
  210. package/examples/settlement_batch/settlement_batch.hsx +0 -19
  211. package/examples/settlement_batch/settlement_batch.udl +0 -757
  212. package/examples/swap/README.md +0 -3
  213. package/examples/swap/swap.hsx +0 -19
  214. package/examples/swap/swap.udl +0 -892
  215. package/examples/threshold_pool/README.md +0 -3
  216. package/examples/threshold_pool/threshold_pool.hsx +0 -16
  217. package/examples/threshold_pool/threshold_pool.udl +0 -680
  218. package/examples/weighted_distribution/README.md +0 -3
  219. package/examples/weighted_distribution/weighted_distribution.hsx +0 -20
  220. package/examples/weighted_distribution/weighted_distribution.udl +0 -348
  221. package/skills/hsx/SKILL.md +0 -449
  222. package/src/diagnostics.ts +0 -620
  223. package/src/emit.ts +0 -282
  224. package/src/entry-overrides.ts +0 -428
  225. package/src/ir.ts +0 -113
  226. package/src/limits.ts +0 -22
  227. package/src/lsp/server.ts +0 -460
  228. package/src/modules.ts +0 -452
  229. package/src/typecheck.ts +0 -5381
  230. package/std/SEMANTICS.md +0 -44
  231. package/std/money_flows/advance.hsx +0 -235
  232. package/std/money_flows/cancellable_booking.hsx +0 -402
  233. package/std/money_flows/captured_payment.hsx +0 -220
  234. package/std/money_flows/conditional_disbursement.hsx +0 -226
  235. package/std/money_flows/credit_facility.hsx +0 -214
  236. package/std/money_flows/held_payment.hsx +0 -812
  237. package/std/money_flows/index.hsx +0 -4
  238. package/std/money_flows/instant_transfer.hsx +0 -231
  239. package/std/money_flows/metered.hsx +0 -104
  240. package/std/money_flows/pooled_split.hsx +0 -109
  241. package/std/money_flows/premium_forward.hsx +0 -307
  242. package/std/money_flows/reconciled_payout.hsx +0 -119
  243. package/std/money_flows/rotating_pool.hsx +0 -305
  244. package/std/money_flows/scheduled.hsx +0 -599
  245. package/std/money_flows/security_deposit.hsx +0 -248
  246. package/std/money_flows/settlement_batch.hsx +0 -173
  247. package/std/money_flows/swap.hsx +0 -1192
  248. package/std/money_flows/threshold_pool.hsx +0 -307
  249. package/std/money_flows/weighted_distribution.hsx +0 -237
@@ -1,1396 +0,0 @@
1
- {
2
- "instruments": [
3
- {
4
- "actionOrder": [
5
- "create",
6
- "approve",
7
- "collect_installment_1",
8
- "mark_installment_1_delinquent",
9
- "collect_installment_2",
10
- "mark_installment_2_delinquent",
11
- "complete",
12
- "write_off"
13
- ],
14
- "actions": {
15
- "approve": {
16
- "agentDescription": "Approve the draft obligation and freeze its principal partition and due anchors. The obligation must be in draft. No money moves. Where the product advances funds, approve is what makes advance available.",
17
- "moves": [],
18
- "publicAction": "approveRepayment",
19
- "steps": [],
20
- "summary": "Approve the immutable principal partition and stored anchors"
21
- },
22
- "collect_installment_1": {
23
- "due": {
24
- "field": "firstDueAt"
25
- },
26
- "effects": {
27
- "reads": [
28
- {
29
- "signature": "reads.requires_aggregate",
30
- "source": "requiresAggregate"
31
- }
32
- ],
33
- "schedules": [
34
- {
35
- "signature": "schedules.due",
36
- "source": "due"
37
- }
38
- ]
39
- },
40
- "moves": [],
41
- "requiresAggregate": [
42
- {
43
- "check": {
44
- "amountField": "amount",
45
- "kind": "sum_exactly",
46
- "targetField": "installment1Amount"
47
- },
48
- "instrumentId": "repayment_installment_1_payment",
49
- "over": "children",
50
- "refField": "repaymentId",
51
- "statuses": [
52
- "paid"
53
- ]
54
- }
55
- ],
56
- "steps": [],
57
- "summary": "Close delinquent installment 1 after linked payments reach its stored amount"
58
- },
59
- "collect_installment_2": {
60
- "due": {
61
- "field": "firstDueAt",
62
- "offset": "P30D"
63
- },
64
- "effects": {
65
- "reads": [
66
- {
67
- "signature": "reads.requires_aggregate",
68
- "source": "requiresAggregate"
69
- }
70
- ],
71
- "schedules": [
72
- {
73
- "signature": "schedules.due",
74
- "source": "due"
75
- }
76
- ]
77
- },
78
- "moves": [],
79
- "requiresAggregate": [
80
- {
81
- "check": {
82
- "amountField": "amount",
83
- "kind": "sum_exactly",
84
- "targetField": "installment2Amount"
85
- },
86
- "instrumentId": "repayment_installment_2_payment",
87
- "over": "children",
88
- "refField": "repaymentId",
89
- "statuses": [
90
- "paid"
91
- ]
92
- }
93
- ],
94
- "steps": [],
95
- "summary": "Close delinquent installment 2 after linked payments reach its stored amount"
96
- },
97
- "complete": {
98
- "due": {
99
- "field": "firstDueAt",
100
- "offset": "P30D"
101
- },
102
- "effects": {
103
- "reads": [
104
- {
105
- "signature": "reads.requires_aggregate",
106
- "source": "requiresAggregate"
107
- }
108
- ],
109
- "schedules": [
110
- {
111
- "signature": "schedules.due",
112
- "source": "due"
113
- }
114
- ]
115
- },
116
- "moves": [],
117
- "requiresAggregate": [
118
- {
119
- "check": {
120
- "amountField": "amount",
121
- "kind": "sum_exactly",
122
- "targetField": "installment1Amount"
123
- },
124
- "instrumentId": "repayment_installment_1_payment",
125
- "over": "children",
126
- "refField": "repaymentId",
127
- "statuses": [
128
- "paid"
129
- ]
130
- },
131
- {
132
- "check": {
133
- "amountField": "amount",
134
- "kind": "sum_exactly",
135
- "targetField": "installment2Amount"
136
- },
137
- "instrumentId": "repayment_installment_2_payment",
138
- "over": "children",
139
- "refField": "repaymentId",
140
- "statuses": [
141
- "paid"
142
- ]
143
- }
144
- ],
145
- "steps": [],
146
- "summary": "Close the obligation only after every stored anchor is paid exactly"
147
- },
148
- "create": {
149
- "agentDescription": "Create the obligation in draft with its principal split across stored installment anchors. Approve is the next call. Where the product declares a derived fee, creating the obligation also moves that fee from its bearer to the platform account.",
150
- "moves": [],
151
- "publicAction": "createRepayment",
152
- "steps": [],
153
- "summary": "Create a repayment obligation"
154
- },
155
- "mark_installment_1_delinquent": {
156
- "due": {
157
- "field": "firstDueAt"
158
- },
159
- "effects": {
160
- "reads": [
161
- {
162
- "signature": "reads.requires_aggregate",
163
- "source": "requiresAggregate"
164
- }
165
- ],
166
- "schedules": [
167
- {
168
- "signature": "schedules.due",
169
- "source": "due"
170
- }
171
- ]
172
- },
173
- "moves": [],
174
- "requiresAggregate": [
175
- {
176
- "check": {
177
- "amountField": "amount",
178
- "kind": "sum_below",
179
- "targetField": "installment1Amount"
180
- },
181
- "instrumentId": "repayment_installment_1_payment",
182
- "over": "children",
183
- "refField": "repaymentId",
184
- "statuses": [
185
- "paid"
186
- ]
187
- }
188
- ],
189
- "setsAt": {
190
- "field": "installment1DelinquentAfter",
191
- "marker": true,
192
- "offset": "PT1S"
193
- },
194
- "steps": [],
195
- "summary": "Mark installment 1 delinquent only when its due anchor is unmet"
196
- },
197
- "mark_installment_2_delinquent": {
198
- "due": {
199
- "field": "firstDueAt",
200
- "offset": "P30D"
201
- },
202
- "effects": {
203
- "reads": [
204
- {
205
- "signature": "reads.requires_aggregate",
206
- "source": "requiresAggregate"
207
- }
208
- ],
209
- "schedules": [
210
- {
211
- "signature": "schedules.due",
212
- "source": "due"
213
- }
214
- ]
215
- },
216
- "moves": [],
217
- "requiresAggregate": [
218
- {
219
- "check": {
220
- "amountField": "amount",
221
- "kind": "sum_below",
222
- "targetField": "installment2Amount"
223
- },
224
- "instrumentId": "repayment_installment_2_payment",
225
- "over": "children",
226
- "refField": "repaymentId",
227
- "statuses": [
228
- "paid"
229
- ]
230
- }
231
- ],
232
- "setsAt": {
233
- "field": "installment2DelinquentAfter",
234
- "marker": true,
235
- "offset": "PT1S"
236
- },
237
- "steps": [],
238
- "summary": "Mark installment 2 delinquent only when its due anchor is unmet"
239
- },
240
- "write_off": {
241
- "agentDescription": "Write off the remaining exposure and stop the obligation. No money moves and nothing is refunded. This is the bookkeeping exit for debt that will not be collected. A written-off obligation never returns to repayment.",
242
- "moves": [],
243
- "publicAction": "writeOffRepayment",
244
- "steps": [],
245
- "summary": "Write off the remaining exposure without moving money"
246
- }
247
- },
248
- "agentDescription": "Reach for scheduled when one payer owes one payee on a calendar. It covers a plan of fixed installments partitioning one total, an obligation whose installments are paid through child payment records and can go delinquent, and an open period charge that repeats until a cancel port fires. Rotating pool is for a group taking turns.",
249
- "aggregateInvariants": [
250
- {
251
- "childField": "amount",
252
- "childInstrumentId": "repayment_installment_1_payment",
253
- "childRefField": "repaymentId",
254
- "childStatuses": [
255
- "paid"
256
- ],
257
- "parentField": "installment1Amount"
258
- },
259
- {
260
- "childField": "amount",
261
- "childInstrumentId": "repayment_installment_2_payment",
262
- "childRefField": "repaymentId",
263
- "childStatuses": [
264
- "paid"
265
- ],
266
- "parentField": "installment2Amount"
267
- }
268
- ],
269
- "description": "Installment obligation for borrower; repayment source pays lender against exact stored anchors",
270
- "fields": {
271
- "borrowerAccountId": {
272
- "description": "The borrower account",
273
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
274
- "type": "string",
275
- "x-hyperscale-reference-filter": {
276
- "column": "role",
277
- "values": [
278
- "customer_balance"
279
- ]
280
- }
281
- },
282
- "currency": {
283
- "description": "ISO 4217 currency code",
284
- "maxLength": 3,
285
- "minLength": 3,
286
- "pattern": "^[A-Z]{3}$",
287
- "type": "string"
288
- },
289
- "firstDueAt": {
290
- "description": "Due date of the first installment; later anchors use fixed offsets of P30D",
291
- "format": "hyperscale-date-time",
292
- "type": "string"
293
- },
294
- "installment1Amount": {
295
- "description": "Stored amount for installment 1 of 2 (carries the integer-division remainder)",
296
- "pattern": "^[1-9][0-9]{0,17}$",
297
- "type": "string",
298
- "x-hyperscale-currency": "SAR"
299
- },
300
- "installment1DelinquentAfter": {
301
- "description": "Machine-set marker proving installment 1 reached its stored due date while unpaid",
302
- "format": "hyperscale-date-time",
303
- "type": "string"
304
- },
305
- "installment2Amount": {
306
- "description": "Stored amount for installment 2 of 2",
307
- "pattern": "^[1-9][0-9]{0,17}$",
308
- "type": "string",
309
- "x-hyperscale-currency": "SAR"
310
- },
311
- "installment2DelinquentAfter": {
312
- "description": "Machine-set marker proving installment 2 reached its stored due date while unpaid",
313
- "format": "hyperscale-date-time",
314
- "type": "string"
315
- },
316
- "lenderAccountId": {
317
- "description": "The lender account",
318
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
319
- "type": "string",
320
- "x-hyperscale-reference-filter": {
321
- "column": "role",
322
- "values": [
323
- "customer_balance"
324
- ]
325
- }
326
- },
327
- "principal": {
328
- "description": "The principal in SAR minor units; the stored installment anchors partition it exactly",
329
- "pattern": "^[1-9][0-9]{0,17}$",
330
- "type": "string",
331
- "x-hyperscale-currency": "SAR"
332
- },
333
- "repaymentSourceAccountId": {
334
- "description": "The repayment source account",
335
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
336
- "type": "string",
337
- "x-hyperscale-reference-filter": {
338
- "column": "role",
339
- "values": [
340
- "customer_balance"
341
- ]
342
- }
343
- }
344
- },
345
- "id": "repayment",
346
- "idPrefix": "repa",
347
- "lifecycle": {
348
- "initial": "draft",
349
- "states": [
350
- "draft",
351
- "active",
352
- "installment_1_delinquent",
353
- "installment_2_delinquent",
354
- "written_off",
355
- "repaid"
356
- ],
357
- "transitions": {
358
- "approve": {
359
- "from": [
360
- "draft"
361
- ],
362
- "to": "active"
363
- },
364
- "collect_installment_1": {
365
- "from": [
366
- "installment_1_delinquent",
367
- "installment_2_delinquent"
368
- ],
369
- "to": "active"
370
- },
371
- "collect_installment_2": {
372
- "from": [
373
- "installment_1_delinquent",
374
- "installment_2_delinquent"
375
- ],
376
- "to": "active"
377
- },
378
- "complete": {
379
- "from": [
380
- "active",
381
- "installment_1_delinquent",
382
- "installment_2_delinquent"
383
- ],
384
- "to": "repaid"
385
- },
386
- "mark_installment_1_delinquent": {
387
- "from": [
388
- "active",
389
- "installment_2_delinquent"
390
- ],
391
- "to": "installment_1_delinquent"
392
- },
393
- "mark_installment_2_delinquent": {
394
- "from": [
395
- "active",
396
- "installment_1_delinquent"
397
- ],
398
- "to": "installment_2_delinquent"
399
- },
400
- "write_off": {
401
- "from": [
402
- "draft",
403
- "active",
404
- "installment_1_delinquent",
405
- "installment_2_delinquent"
406
- ],
407
- "to": "written_off"
408
- }
409
- }
410
- },
411
- "parties": {
412
- "beneficiary": "lenderAccountId",
413
- "payer": "repaymentSourceAccountId"
414
- },
415
- "partitions": [
416
- {
417
- "pieceFields": [
418
- "installment1Amount",
419
- "installment2Amount"
420
- ],
421
- "totalField": "principal"
422
- }
423
- ],
424
- "required": [
425
- "lenderAccountId",
426
- "repaymentSourceAccountId",
427
- "currency",
428
- "principal",
429
- "firstDueAt",
430
- "installment1Amount",
431
- "installment2Amount"
432
- ],
433
- "summary": "2-anchor obligation for borrower",
434
- "templateBinding": {
435
- "id": "scheduled",
436
- "parameters": {
437
- "advanceTo": false,
438
- "count": 2,
439
- "derivedAmount": false,
440
- "mandate": false,
441
- "monthEnd": false,
442
- "periodLiability": false,
443
- "terminationDrain": false,
444
- "until": false
445
- }
446
- },
447
- "title": "Repayment"
448
- },
449
- {
450
- "actionOrder": [
451
- "create",
452
- "repay",
453
- "refund"
454
- ],
455
- "actions": {
456
- "create": {
457
- "agentDescription": "Open a payment record against installment 1. The parent obligation must be live. No money moves yet. Repay is what pays.",
458
- "effects": {
459
- "reads": [
460
- {
461
- "signature": "reads.requires_refs",
462
- "source": "requiresRefs"
463
- }
464
- ]
465
- },
466
- "moves": [],
467
- "publicAction": "createRepaymentInstallment1Payment",
468
- "requiresRefs": [
469
- {
470
- "bind": {
471
- "currency": "fields.currency",
472
- "lenderAccountId": "fields.lenderAccountId",
473
- "repaymentSourceAccountId": "fields.repaymentSourceAccountId"
474
- },
475
- "field": "repaymentId",
476
- "statuses": [
477
- "active",
478
- "installment_1_delinquent",
479
- "installment_2_delinquent"
480
- ]
481
- }
482
- ],
483
- "steps": [],
484
- "summary": "Create a payment record for installment 1"
485
- },
486
- "refund": {
487
- "agentDescription": "Return one whole installment 1 payment to the payer. The record must be paid, and the refund is always its full amount, so split a payment across records when a partial refund could be needed. This moves money back.",
488
- "effects": {
489
- "moves": [
490
- {
491
- "signature": "moves.transfer.internal",
492
- "source": "moves[0]"
493
- }
494
- ],
495
- "reads": [
496
- {
497
- "signature": "reads.requires_refs",
498
- "source": "requiresRefs"
499
- }
500
- ]
501
- },
502
- "moves": [
503
- {
504
- "bind": {
505
- "amount": {
506
- "from": "instance",
507
- "path": "fields.amount"
508
- },
509
- "currency": {
510
- "from": "const",
511
- "value": "SAR"
512
- },
513
- "destinationAccountId": {
514
- "from": "instance",
515
- "path": "fields.repaymentSourceAccountId"
516
- },
517
- "metadata.instrumentId": {
518
- "from": "const",
519
- "value": "repayment_installment_1_payment"
520
- },
521
- "metadata.instrumentInstanceId": {
522
- "from": "instance",
523
- "path": "instrumentInstanceId"
524
- },
525
- "metadata.phase": {
526
- "from": "const",
527
- "value": "refund"
528
- },
529
- "productId": {
530
- "from": "instance",
531
- "path": "productId"
532
- },
533
- "sourceAccountId": {
534
- "from": "instance",
535
- "path": "fields.lenderAccountId"
536
- }
537
- },
538
- "capture": {
539
- "refundRefundTransferId": "transferId"
540
- },
541
- "key": "refund",
542
- "operation": "internal_transfer.create"
543
- }
544
- ],
545
- "publicAction": "refundRepaymentInstallment1Payment",
546
- "requiresRefs": [
547
- {
548
- "field": "repaymentId",
549
- "match": {
550
- "fields.currency": "fields.currency",
551
- "fields.lenderAccountId": "fields.lenderAccountId",
552
- "fields.repaymentSourceAccountId": "fields.repaymentSourceAccountId"
553
- },
554
- "statuses": [
555
- "active",
556
- "installment_1_delinquent",
557
- "installment_2_delinquent"
558
- ]
559
- }
560
- ],
561
- "steps": [],
562
- "summary": "Refund this one stored installment 1 payment whole"
563
- },
564
- "repay": {
565
- "agentDescription": "Pay this record's amount toward installment 1. The record must be created and its obligation live. Refused when this amount plus the records already paid against that installment would pass the stored amount. This moves the payer's money. Where a mandate applies, its declared parties may call it and an evidence reference is required.",
566
- "effects": {
567
- "moves": [
568
- {
569
- "signature": "moves.transfer.internal",
570
- "source": "moves[0]"
571
- }
572
- ],
573
- "reads": [
574
- {
575
- "signature": "reads.requires_refs",
576
- "source": "requiresRefs"
577
- }
578
- ]
579
- },
580
- "moves": [
581
- {
582
- "bind": {
583
- "amount": {
584
- "from": "instance",
585
- "path": "fields.amount"
586
- },
587
- "currency": {
588
- "from": "const",
589
- "value": "SAR"
590
- },
591
- "destinationAccountId": {
592
- "from": "instance",
593
- "path": "fields.lenderAccountId"
594
- },
595
- "metadata.instrumentId": {
596
- "from": "const",
597
- "value": "repayment_installment_1_payment"
598
- },
599
- "metadata.instrumentInstanceId": {
600
- "from": "instance",
601
- "path": "instrumentInstanceId"
602
- },
603
- "metadata.phase": {
604
- "from": "const",
605
- "value": "repay"
606
- },
607
- "productId": {
608
- "from": "instance",
609
- "path": "productId"
610
- },
611
- "sourceAccountId": {
612
- "from": "instance",
613
- "path": "fields.repaymentSourceAccountId"
614
- }
615
- },
616
- "capture": {
617
- "repayRepaymentTransferId": "transferId"
618
- },
619
- "key": "repayment",
620
- "operation": "internal_transfer.create"
621
- }
622
- ],
623
- "publicAction": "repayRepaymentInstallment1Payment",
624
- "requiresExposure": [
625
- {
626
- "amountField": "amount",
627
- "anchorField": "repaymentId",
628
- "capField": "installment1Amount",
629
- "capOnAnchor": true,
630
- "childInstrumentId": "repayment_installment_1_payment",
631
- "statuses": [
632
- "paid"
633
- ]
634
- }
635
- ],
636
- "requiresRefs": [
637
- {
638
- "field": "repaymentId",
639
- "match": {
640
- "fields.currency": "fields.currency",
641
- "fields.lenderAccountId": "fields.lenderAccountId",
642
- "fields.repaymentSourceAccountId": "fields.repaymentSourceAccountId"
643
- },
644
- "statuses": [
645
- "active",
646
- "installment_1_delinquent",
647
- "installment_2_delinquent"
648
- ]
649
- }
650
- ],
651
- "steps": [],
652
- "summary": "Pay a partial or full amount against installment 1"
653
- }
654
- },
655
- "agentDescription": "One payment against installment 1 of the obligation. Payments can be partial, so create a record, repay it, and the parent installment closes once its paid records sum to the stored anchor amount.",
656
- "description": "One partial or full payment bound to installment 1 of repayment; the operation name fixes the anchor and repaymentId fixes the obligation",
657
- "fields": {
658
- "amount": {
659
- "description": "Positive payment amount capped with its paid siblings at installment1Amount",
660
- "pattern": "^[1-9][0-9]{0,17}$",
661
- "type": "string",
662
- "x-hyperscale-currency": "SAR"
663
- },
664
- "currency": {
665
- "description": "ISO 4217 currency code",
666
- "maxLength": 3,
667
- "minLength": 3,
668
- "pattern": "^[A-Z]{3}$",
669
- "type": "string"
670
- },
671
- "lenderAccountId": {
672
- "description": "The lender account",
673
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
674
- "type": "string",
675
- "x-hyperscale-reference-filter": {
676
- "column": "role",
677
- "values": [
678
- "customer_balance"
679
- ]
680
- }
681
- },
682
- "repaymentId": {
683
- "description": "The exact repayment this payment belongs to",
684
- "pattern": "^repa_(sandbox|live)_[a-z0-9]{8,64}$",
685
- "type": "string"
686
- },
687
- "repaymentSourceAccountId": {
688
- "description": "The repayment source account",
689
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
690
- "type": "string",
691
- "x-hyperscale-reference-filter": {
692
- "column": "role",
693
- "values": [
694
- "customer_balance"
695
- ]
696
- }
697
- }
698
- },
699
- "id": "repayment_installment_1_payment",
700
- "idPrefix": "zzaa",
701
- "lifecycle": {
702
- "initial": "created",
703
- "states": [
704
- "created",
705
- "paid",
706
- "refunded"
707
- ],
708
- "transitions": {
709
- "refund": {
710
- "from": [
711
- "paid"
712
- ],
713
- "to": "refunded"
714
- },
715
- "repay": {
716
- "from": [
717
- "created"
718
- ],
719
- "to": "paid"
720
- }
721
- }
722
- },
723
- "parties": {
724
- "beneficiary": "lenderAccountId",
725
- "payer": "repaymentSourceAccountId"
726
- },
727
- "required": [
728
- "lenderAccountId",
729
- "repaymentSourceAccountId",
730
- "amount",
731
- "currency",
732
- "repaymentId"
733
- ],
734
- "summary": "Anchor-bound payment for installment 1",
735
- "title": "Repayment Installment 1 Payment"
736
- },
737
- {
738
- "actionOrder": [
739
- "create",
740
- "repay",
741
- "refund"
742
- ],
743
- "actions": {
744
- "create": {
745
- "agentDescription": "Open a payment record against installment 2. The parent obligation must be live. No money moves yet. Repay is what pays.",
746
- "effects": {
747
- "reads": [
748
- {
749
- "signature": "reads.requires_refs",
750
- "source": "requiresRefs"
751
- }
752
- ]
753
- },
754
- "moves": [],
755
- "publicAction": "createRepaymentInstallment2Payment",
756
- "requiresRefs": [
757
- {
758
- "bind": {
759
- "currency": "fields.currency",
760
- "lenderAccountId": "fields.lenderAccountId",
761
- "repaymentSourceAccountId": "fields.repaymentSourceAccountId"
762
- },
763
- "field": "repaymentId",
764
- "statuses": [
765
- "active",
766
- "installment_1_delinquent",
767
- "installment_2_delinquent"
768
- ]
769
- }
770
- ],
771
- "steps": [],
772
- "summary": "Create a payment record for installment 2"
773
- },
774
- "refund": {
775
- "agentDescription": "Return one whole installment 2 payment to the payer. The record must be paid, and the refund is always its full amount, so split a payment across records when a partial refund could be needed. This moves money back.",
776
- "effects": {
777
- "moves": [
778
- {
779
- "signature": "moves.transfer.internal",
780
- "source": "moves[0]"
781
- }
782
- ],
783
- "reads": [
784
- {
785
- "signature": "reads.requires_refs",
786
- "source": "requiresRefs"
787
- }
788
- ]
789
- },
790
- "moves": [
791
- {
792
- "bind": {
793
- "amount": {
794
- "from": "instance",
795
- "path": "fields.amount"
796
- },
797
- "currency": {
798
- "from": "const",
799
- "value": "SAR"
800
- },
801
- "destinationAccountId": {
802
- "from": "instance",
803
- "path": "fields.repaymentSourceAccountId"
804
- },
805
- "metadata.instrumentId": {
806
- "from": "const",
807
- "value": "repayment_installment_2_payment"
808
- },
809
- "metadata.instrumentInstanceId": {
810
- "from": "instance",
811
- "path": "instrumentInstanceId"
812
- },
813
- "metadata.phase": {
814
- "from": "const",
815
- "value": "refund"
816
- },
817
- "productId": {
818
- "from": "instance",
819
- "path": "productId"
820
- },
821
- "sourceAccountId": {
822
- "from": "instance",
823
- "path": "fields.lenderAccountId"
824
- }
825
- },
826
- "capture": {
827
- "refundRefundTransferId": "transferId"
828
- },
829
- "key": "refund",
830
- "operation": "internal_transfer.create"
831
- }
832
- ],
833
- "publicAction": "refundRepaymentInstallment2Payment",
834
- "requiresRefs": [
835
- {
836
- "field": "repaymentId",
837
- "match": {
838
- "fields.currency": "fields.currency",
839
- "fields.lenderAccountId": "fields.lenderAccountId",
840
- "fields.repaymentSourceAccountId": "fields.repaymentSourceAccountId"
841
- },
842
- "statuses": [
843
- "active",
844
- "installment_1_delinquent",
845
- "installment_2_delinquent"
846
- ]
847
- }
848
- ],
849
- "steps": [],
850
- "summary": "Refund this one stored installment 2 payment whole"
851
- },
852
- "repay": {
853
- "agentDescription": "Pay this record's amount toward installment 2. The record must be created and its obligation live. Refused when this amount plus the records already paid against that installment would pass the stored amount. This moves the payer's money. Where a mandate applies, its declared parties may call it and an evidence reference is required.",
854
- "effects": {
855
- "moves": [
856
- {
857
- "signature": "moves.transfer.internal",
858
- "source": "moves[0]"
859
- }
860
- ],
861
- "reads": [
862
- {
863
- "signature": "reads.requires_refs",
864
- "source": "requiresRefs"
865
- }
866
- ]
867
- },
868
- "moves": [
869
- {
870
- "bind": {
871
- "amount": {
872
- "from": "instance",
873
- "path": "fields.amount"
874
- },
875
- "currency": {
876
- "from": "const",
877
- "value": "SAR"
878
- },
879
- "destinationAccountId": {
880
- "from": "instance",
881
- "path": "fields.lenderAccountId"
882
- },
883
- "metadata.instrumentId": {
884
- "from": "const",
885
- "value": "repayment_installment_2_payment"
886
- },
887
- "metadata.instrumentInstanceId": {
888
- "from": "instance",
889
- "path": "instrumentInstanceId"
890
- },
891
- "metadata.phase": {
892
- "from": "const",
893
- "value": "repay"
894
- },
895
- "productId": {
896
- "from": "instance",
897
- "path": "productId"
898
- },
899
- "sourceAccountId": {
900
- "from": "instance",
901
- "path": "fields.repaymentSourceAccountId"
902
- }
903
- },
904
- "capture": {
905
- "repayRepaymentTransferId": "transferId"
906
- },
907
- "key": "repayment",
908
- "operation": "internal_transfer.create"
909
- }
910
- ],
911
- "publicAction": "repayRepaymentInstallment2Payment",
912
- "requiresExposure": [
913
- {
914
- "amountField": "amount",
915
- "anchorField": "repaymentId",
916
- "capField": "installment2Amount",
917
- "capOnAnchor": true,
918
- "childInstrumentId": "repayment_installment_2_payment",
919
- "statuses": [
920
- "paid"
921
- ]
922
- }
923
- ],
924
- "requiresRefs": [
925
- {
926
- "field": "repaymentId",
927
- "match": {
928
- "fields.currency": "fields.currency",
929
- "fields.lenderAccountId": "fields.lenderAccountId",
930
- "fields.repaymentSourceAccountId": "fields.repaymentSourceAccountId"
931
- },
932
- "statuses": [
933
- "active",
934
- "installment_1_delinquent",
935
- "installment_2_delinquent"
936
- ]
937
- }
938
- ],
939
- "steps": [],
940
- "summary": "Pay a partial or full amount against installment 2"
941
- }
942
- },
943
- "agentDescription": "One payment against installment 2 of the obligation. Payments can be partial, so create a record, repay it, and the parent installment closes once its paid records sum to the stored anchor amount.",
944
- "description": "One partial or full payment bound to installment 2 of repayment; the operation name fixes the anchor and repaymentId fixes the obligation",
945
- "fields": {
946
- "amount": {
947
- "description": "Positive payment amount capped with its paid siblings at installment2Amount",
948
- "pattern": "^[1-9][0-9]{0,17}$",
949
- "type": "string",
950
- "x-hyperscale-currency": "SAR"
951
- },
952
- "currency": {
953
- "description": "ISO 4217 currency code",
954
- "maxLength": 3,
955
- "minLength": 3,
956
- "pattern": "^[A-Z]{3}$",
957
- "type": "string"
958
- },
959
- "lenderAccountId": {
960
- "description": "The lender account",
961
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
962
- "type": "string",
963
- "x-hyperscale-reference-filter": {
964
- "column": "role",
965
- "values": [
966
- "customer_balance"
967
- ]
968
- }
969
- },
970
- "repaymentId": {
971
- "description": "The exact repayment this payment belongs to",
972
- "pattern": "^repa_(sandbox|live)_[a-z0-9]{8,64}$",
973
- "type": "string"
974
- },
975
- "repaymentSourceAccountId": {
976
- "description": "The repayment source account",
977
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
978
- "type": "string",
979
- "x-hyperscale-reference-filter": {
980
- "column": "role",
981
- "values": [
982
- "customer_balance"
983
- ]
984
- }
985
- }
986
- },
987
- "id": "repayment_installment_2_payment",
988
- "idPrefix": "zzab",
989
- "lifecycle": {
990
- "initial": "created",
991
- "states": [
992
- "created",
993
- "paid",
994
- "refunded"
995
- ],
996
- "transitions": {
997
- "refund": {
998
- "from": [
999
- "paid"
1000
- ],
1001
- "to": "refunded"
1002
- },
1003
- "repay": {
1004
- "from": [
1005
- "created"
1006
- ],
1007
- "to": "paid"
1008
- }
1009
- }
1010
- },
1011
- "parties": {
1012
- "beneficiary": "lenderAccountId",
1013
- "payer": "repaymentSourceAccountId"
1014
- },
1015
- "required": [
1016
- "lenderAccountId",
1017
- "repaymentSourceAccountId",
1018
- "amount",
1019
- "currency",
1020
- "repaymentId"
1021
- ],
1022
- "summary": "Anchor-bound payment for installment 2",
1023
- "title": "Repayment Installment 2 Payment"
1024
- },
1025
- {
1026
- "actionOrder": [
1027
- "create",
1028
- "freeze",
1029
- "close"
1030
- ],
1031
- "actions": {
1032
- "close": {
1033
- "agentDescription": "Close the facility for good. Every draw under it must already be resolved, so clear the outstanding obligations first. No money moves and a closed facility never lends again.",
1034
- "effects": {
1035
- "reads": [
1036
- {
1037
- "signature": "reads.requires_aggregate",
1038
- "source": "requiresAggregate"
1039
- }
1040
- ]
1041
- },
1042
- "moves": [],
1043
- "publicAction": "closeFacility",
1044
- "requiresAggregate": [
1045
- {
1046
- "check": {
1047
- "kind": "all_in"
1048
- },
1049
- "instrumentId": "facility_draw",
1050
- "over": "children",
1051
- "refField": "facilityId",
1052
- "statuses": [
1053
- "resolved"
1054
- ]
1055
- }
1056
- ],
1057
- "steps": [],
1058
- "summary": "Close only when every admitted draw resolved"
1059
- },
1060
- "create": {
1061
- "agentDescription": "Open the facility before any draw exists. The caller supplies the facilityLimit, the currency, the borrower and lender accounts, the draw destination account, and the stored expiry. No money moves.",
1062
- "moves": [],
1063
- "publicAction": "createFacility",
1064
- "steps": [],
1065
- "summary": "Open the facility"
1066
- },
1067
- "freeze": {
1068
- "due": {
1069
- "field": "expiresAt"
1070
- },
1071
- "effects": {
1072
- "schedules": [
1073
- {
1074
- "signature": "schedules.due",
1075
- "source": "due"
1076
- }
1077
- ]
1078
- },
1079
- "moves": [],
1080
- "steps": [],
1081
- "summary": "Freeze new draws at expiry"
1082
- }
1083
- },
1084
- "agentDescription": "Reach for credit facility when the lender gives the borrower reusable capacity up to facilityLimit and every draw is repaid through its own scheduled obligation. Capacity frees up as each obligation resolves. Pick advance for one up-front payment with no reusable limit.",
1085
- "description": "Reusable capacity with repayment delegated to one scheduled obligation",
1086
- "fields": {
1087
- "borrowerAccountId": {
1088
- "description": "The borrower account",
1089
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1090
- "type": "string",
1091
- "x-hyperscale-reference-filter": {
1092
- "column": "role",
1093
- "values": [
1094
- "customer_balance"
1095
- ]
1096
- }
1097
- },
1098
- "currency": {
1099
- "description": "ISO 4217 currency code",
1100
- "maxLength": 3,
1101
- "minLength": 3,
1102
- "pattern": "^[A-Z]{3}$",
1103
- "type": "string"
1104
- },
1105
- "drawDestinationAccountId": {
1106
- "description": "The draw destination account",
1107
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1108
- "type": "string",
1109
- "x-hyperscale-reference-filter": {
1110
- "column": "role",
1111
- "values": [
1112
- "customer_balance"
1113
- ]
1114
- }
1115
- },
1116
- "expiresAt": {
1117
- "description": "Stored draw expiry",
1118
- "format": "hyperscale-date-time",
1119
- "type": "string"
1120
- },
1121
- "facilityLimit": {
1122
- "description": "Facility limit in SAR minor units",
1123
- "pattern": "^[1-9][0-9]{0,17}$",
1124
- "type": "string",
1125
- "x-hyperscale-currency": "SAR"
1126
- },
1127
- "lenderAccountId": {
1128
- "description": "The lender account",
1129
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1130
- "type": "string",
1131
- "x-hyperscale-reference-filter": {
1132
- "column": "role",
1133
- "values": [
1134
- "customer_balance"
1135
- ]
1136
- }
1137
- }
1138
- },
1139
- "id": "facility",
1140
- "idPrefix": "faci",
1141
- "lifecycle": {
1142
- "initial": "active",
1143
- "states": [
1144
- "active",
1145
- "frozen",
1146
- "closed"
1147
- ],
1148
- "transitions": {
1149
- "close": {
1150
- "from": [
1151
- "active",
1152
- "frozen"
1153
- ],
1154
- "to": "closed"
1155
- },
1156
- "freeze": {
1157
- "from": [
1158
- "active"
1159
- ],
1160
- "to": "frozen"
1161
- }
1162
- }
1163
- },
1164
- "parties": {
1165
- "beneficiary": "drawDestinationAccountId",
1166
- "payer": "lenderAccountId"
1167
- },
1168
- "required": [
1169
- "borrowerAccountId",
1170
- "drawDestinationAccountId",
1171
- "lenderAccountId",
1172
- "currency",
1173
- "facilityLimit",
1174
- "expiresAt"
1175
- ],
1176
- "summary": "Draw capacity for borrower",
1177
- "templateBinding": {
1178
- "id": "credit_facility",
1179
- "parameters": {}
1180
- },
1181
- "title": "Facility"
1182
- },
1183
- {
1184
- "actionOrder": [
1185
- "create",
1186
- "resolve"
1187
- ],
1188
- "actions": {
1189
- "create": {
1190
- "agentDescription": "Draw one amount out of the facility to the draw destination account. The facility must be active, the linked obligation active and bound to no other draw, and the drawn amounts plus this one must stay within facilityLimit. The money leaves the lender straight away.",
1191
- "effects": {
1192
- "moves": [
1193
- {
1194
- "signature": "moves.transfer.internal",
1195
- "source": "moves[0]"
1196
- }
1197
- ],
1198
- "reads": [
1199
- {
1200
- "signature": "reads.requires_refs",
1201
- "source": "requiresRefs"
1202
- }
1203
- ]
1204
- },
1205
- "moves": [
1206
- {
1207
- "bind": {
1208
- "amount": {
1209
- "from": "instance",
1210
- "path": "fields.amount"
1211
- },
1212
- "currency": {
1213
- "from": "const",
1214
- "value": "SAR"
1215
- },
1216
- "destinationAccountId": {
1217
- "from": "instance",
1218
- "path": "fields.drawDestinationAccountId"
1219
- },
1220
- "metadata.instrumentId": {
1221
- "from": "const",
1222
- "value": "facility_draw"
1223
- },
1224
- "metadata.instrumentInstanceId": {
1225
- "from": "instance",
1226
- "path": "instrumentInstanceId"
1227
- },
1228
- "metadata.phase": {
1229
- "from": "const",
1230
- "value": "create"
1231
- },
1232
- "productId": {
1233
- "from": "instance",
1234
- "path": "productId"
1235
- },
1236
- "sourceAccountId": {
1237
- "from": "instance",
1238
- "path": "fields.lenderAccountId"
1239
- }
1240
- },
1241
- "capture": {
1242
- "createDrawTransferId": "transferId"
1243
- },
1244
- "key": "draw",
1245
- "operation": "internal_transfer.create"
1246
- }
1247
- ],
1248
- "publicAction": "createFacilityDraw",
1249
- "requiresExposure": [
1250
- {
1251
- "amountField": "amount",
1252
- "anchorField": "facilityId",
1253
- "capField": "facilityLimit",
1254
- "capOnAnchor": true,
1255
- "childInstrumentId": "facility_draw",
1256
- "statuses": [
1257
- "drawn"
1258
- ]
1259
- }
1260
- ],
1261
- "requiresRefs": [
1262
- {
1263
- "bind": {
1264
- "currency": "fields.currency",
1265
- "drawDestinationAccountId": "fields.drawDestinationAccountId",
1266
- "lenderAccountId": "fields.lenderAccountId"
1267
- },
1268
- "field": "facilityId",
1269
- "statuses": [
1270
- "active"
1271
- ]
1272
- },
1273
- {
1274
- "field": "repaymentId",
1275
- "statuses": [
1276
- "active"
1277
- ],
1278
- "unique": true
1279
- }
1280
- ],
1281
- "steps": [],
1282
- "summary": "Create one draw under the locked facility capacity"
1283
- },
1284
- "resolve": {
1285
- "agentDescription": "Free the drawn capacity back to the facility. The linked obligation must already be repaid or written off. No money moves here, the obligation did the repaying.",
1286
- "effects": {
1287
- "reads": [
1288
- {
1289
- "signature": "reads.requires_refs",
1290
- "source": "requiresRefs"
1291
- }
1292
- ]
1293
- },
1294
- "moves": [],
1295
- "publicAction": "resolveFacilityDraw",
1296
- "requiresRefs": [
1297
- {
1298
- "field": "repaymentId",
1299
- "statuses": [
1300
- "repaid",
1301
- "written_off"
1302
- ]
1303
- }
1304
- ],
1305
- "steps": [],
1306
- "summary": "Release revolving capacity only after the linked obligation resolves"
1307
- }
1308
- },
1309
- "agentDescription": "Reach for this child row to take one draw against a facility. The parent carries the facilityLimit, this row carries one drawn amount and the single obligation that repays it.",
1310
- "description": "One capacity-capped draw linked to obligation",
1311
- "fields": {
1312
- "amount": {
1313
- "description": "One draw amount",
1314
- "pattern": "^[1-9][0-9]{0,17}$",
1315
- "type": "string",
1316
- "x-hyperscale-currency": "SAR"
1317
- },
1318
- "currency": {
1319
- "description": "ISO 4217 currency code",
1320
- "maxLength": 3,
1321
- "minLength": 3,
1322
- "pattern": "^[A-Z]{3}$",
1323
- "type": "string"
1324
- },
1325
- "drawDestinationAccountId": {
1326
- "description": "The draw destination account",
1327
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1328
- "type": "string",
1329
- "x-hyperscale-reference-filter": {
1330
- "column": "role",
1331
- "values": [
1332
- "customer_balance"
1333
- ]
1334
- }
1335
- },
1336
- "facilityId": {
1337
- "description": "The exact facility",
1338
- "pattern": "^faci_(sandbox|live)_[a-z0-9]{8,64}$",
1339
- "type": "string"
1340
- },
1341
- "lenderAccountId": {
1342
- "description": "The lender account",
1343
- "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
1344
- "type": "string",
1345
- "x-hyperscale-reference-filter": {
1346
- "column": "role",
1347
- "values": [
1348
- "customer_balance"
1349
- ]
1350
- }
1351
- },
1352
- "repaymentId": {
1353
- "description": "The sole repayment obligation",
1354
- "pattern": "^repa_(sandbox|live)_[a-z0-9]{8,64}$",
1355
- "type": "string"
1356
- }
1357
- },
1358
- "id": "facility_draw",
1359
- "idPrefix": "zzac",
1360
- "lifecycle": {
1361
- "initial": "drawn",
1362
- "states": [
1363
- "drawn",
1364
- "resolved"
1365
- ],
1366
- "transitions": {
1367
- "resolve": {
1368
- "from": [
1369
- "drawn"
1370
- ],
1371
- "to": "resolved"
1372
- }
1373
- }
1374
- },
1375
- "parties": {
1376
- "beneficiary": "drawDestinationAccountId",
1377
- "payer": "lenderAccountId"
1378
- },
1379
- "required": [
1380
- "drawDestinationAccountId",
1381
- "lenderAccountId",
1382
- "amount",
1383
- "currency",
1384
- "facilityId",
1385
- "repaymentId"
1386
- ],
1387
- "summary": "Draw from facility",
1388
- "title": "Facility Draw"
1389
- }
1390
- ],
1391
- "product": "credit_facility_example",
1392
- "subjects": [],
1393
- "title": "Credit facility example",
1394
- "udl": 1,
1395
- "version": 1
1396
- }