@hyperscale0/udl 2.0.4 → 2.1.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 (58) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +15 -1
  3. package/conformance/invalid/call-binds-results.expected.json +10 -0
  4. package/conformance/invalid/call-binds-results.udl +314 -0
  5. package/conformance/invalid/call-unknown-action.expected.json +10 -0
  6. package/conformance/invalid/call-unknown-action.udl +314 -0
  7. package/conformance/invalid/leaf-effect-mismatch.expected.json +10 -0
  8. package/conformance/invalid/leaf-effect-mismatch.udl +314 -0
  9. package/conformance/invalid/piece-plan-without-partition.expected.json +10 -0
  10. package/conformance/invalid/piece-plan-without-partition.udl +305 -0
  11. package/conformance/invalid/private-action-independent-approval.expected.json +10 -0
  12. package/conformance/invalid/private-action-independent-approval.udl +314 -0
  13. package/conformance/invalid/unfund-order-not-reversed.expected.json +10 -0
  14. package/conformance/invalid/unfund-order-not-reversed.udl +314 -0
  15. package/conformance/valid/piece-plan-calls.expected.json +6 -0
  16. package/conformance/valid/piece-plan-calls.udl +314 -0
  17. package/dist/diagnostics.d.ts +36 -0
  18. package/dist/diagnostics.d.ts.map +1 -1
  19. package/dist/diagnostics.js +36 -0
  20. package/dist/diagnostics.js.map +1 -1
  21. package/dist/effects.d.ts +24 -3
  22. package/dist/effects.d.ts.map +1 -1
  23. package/dist/effects.js +906 -8
  24. package/dist/effects.js.map +1 -1
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/limits.d.ts +2 -0
  30. package/dist/limits.d.ts.map +1 -1
  31. package/dist/limits.js +2 -0
  32. package/dist/limits.js.map +1 -1
  33. package/dist/schema.d.ts +594 -11
  34. package/dist/schema.d.ts.map +1 -1
  35. package/dist/schema.js +111 -1
  36. package/dist/schema.js.map +1 -1
  37. package/dist/validation.d.ts.map +1 -1
  38. package/dist/validation.js +289 -4
  39. package/dist/validation.js.map +1 -1
  40. package/docs/assets/brand/manifest.json +30 -0
  41. package/docs/assets/brand/udl-horizontal-white.svg +1 -0
  42. package/docs/assets/brand/udl-horizontal.svg +1 -0
  43. package/docs/assets/brand/udl-stacked-white.svg +1 -0
  44. package/docs/assets/brand/udl-stacked.svg +1 -0
  45. package/docs/assets/udl.svg +7 -14
  46. package/docs/llms-full.txt +199 -32
  47. package/docs/llms.txt +1 -1
  48. package/docs/reference/clauses.md +162 -1
  49. package/docs/reference/cli.md +1 -1
  50. package/docs/reference/diagnostics.md +38 -32
  51. package/package.json +2 -2
  52. package/spec/udl.schema.json +321 -1
  53. package/src/diagnostics.ts +36 -0
  54. package/src/effects.ts +1603 -9
  55. package/src/index.ts +15 -0
  56. package/src/limits.ts +2 -0
  57. package/src/schema.ts +149 -2
  58. package/src/validation.ts +469 -4
package/CHANGELOG.md CHANGED
@@ -8,6 +8,22 @@ Format version and package version are different numbers.
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [2.1.0] - 2026-09-14
12
+
13
+ Published in lockstep with HSX 2.1.0.
14
+
15
+ ### Added
16
+
17
+ - An instrument may declare `piecePlan`: a total field partitioned into named pieces, each with an amount field and immutable release and refund payees, plus `fundOrder`, `releaseOrder`, `refundOrder` and `unfundOrder`. Fund covers every piece, unfund reverses fund, and the other orders may select subsets. Piece amount fields must be distinct and partition the total in one concrete currency; a singleton may bind the total itself.
18
+ - An action may declare `pieceStage` (`plan` and `stage`) to move one piece of a plan. The compiler derives the required `pieceId` input from the selected order and adds no movement of its own; the money flows through the action's `calls`.
19
+ - An action may declare `calls` to typed private actions from an `actionLibrary`, binding parameters from `$instance`, `$piece` or its own inputs and capturing results by name. Private actions never carry independent approval or recovery.
20
+ - Diagnostics `UDL2010` (action graph: cycles, unresolved targets, expansion bound), `UDL2011` (call bindings: forward references, `$results.*`, types), `UDL2012` (call authority: principal, approval and recovery boundary), `UDL2013` (leaf effects and evidence), `UDL4002` (piece partition) and `UDL5013` (piece stage). Each has a conformance case under `conformance/invalid` and a clause reference entry.
21
+ - `resolveUdlActionPlans` exposes the expanded action plans and their diagnostics.
22
+
23
+ ### Changed
24
+
25
+ - The schema specification, clause reference and diagnostics reference are regenerated for the new clauses.
26
+
11
27
  ## [2.0.4] - 2026-09-11
12
28
 
13
29
  - Republished in lockstep with HSX 2.0.4. No format or API change.
package/README.md CHANGED
@@ -1,7 +1,17 @@
1
- ![UDL: The contract between a product and its engine.](docs/assets/udl.svg)
1
+ <p align="left">
2
+ <picture>
3
+ <source media="(max-width: 600px) and (prefers-color-scheme: dark)" srcset="docs/assets/brand/udl-stacked-white.svg">
4
+ <source media="(max-width: 600px)" srcset="docs/assets/brand/udl-stacked.svg">
5
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/brand/udl-horizontal-white.svg">
6
+ <source media="(prefers-color-scheme: light)" srcset="docs/assets/brand/udl-horizontal.svg">
7
+ <img src="docs/assets/brand/udl-horizontal.svg" alt="Hyperscale™ UDL" width="336">
8
+ </picture>
9
+ </p>
2
10
 
3
11
  # UDL
4
12
 
13
+ Hyperscale™ UDL. The canonical contract between a financial product and its engine.
14
+
5
15
  UDL is the Universal Domain Language, the canonical JSON contract for a financial product. One `.udl` file declares subjects, instruments, lifecycles, actions, and money movement. An engine admits that document without reading the source language that produced it. UDL keeps provider machinery below the format: it has no file drops, polling loops, cutoff jobs, scheme messages, or provider statement schemas. The `reconcile` clause names settlement evidence against a declared provider-side row; it does not model provider transport or matching machinery.
6
16
 
7
17
  ## Install
@@ -96,3 +106,7 @@ The evolution diff API (`diffValidatedUdlEvolution`, `diffInstrumentEvolution`,
96
106
  UDL is licensed under AGPL-3.0-only, with a commercial license available from Hyperscale LLC. See [LICENSE](LICENSE), [LICENSING.md](LICENSING.md), and [TRADEMARKS.md](TRADEMARKS.md).
97
107
 
98
108
  Vulnerability reports go through private disclosure as described in [SECURITY.md](SECURITY.md).
109
+
110
+ ---
111
+
112
+ Hyperscale™ is a trademark of Hyperscale LLC. Code licenses do not grant rights to the name or marks.
@@ -0,0 +1,10 @@
1
+ {
2
+ "issues": [
3
+ {
4
+ "code": "UDL2011",
5
+ "path": "$.instruments[0].actions.fund_piece.calls.call_fund.bind.p"
6
+ }
7
+ ],
8
+ "summary": "Call bindings are static; $results is not a binding scope.",
9
+ "verdict": "invalid"
10
+ }
@@ -0,0 +1,314 @@
1
+ {
2
+ "instruments": [
3
+ {
4
+ "actionOrder": [
5
+ "create",
6
+ "fund_piece",
7
+ "payout_piece"
8
+ ],
9
+ "actions": {
10
+ "create": {
11
+ "moves": [],
12
+ "steps": [],
13
+ "summary": "Create watch instrument"
14
+ },
15
+ "fund_piece": {
16
+ "calls": [
17
+ {
18
+ "action": "transfers.execute_fund",
19
+ "bind": {
20
+ "inst": "$instance",
21
+ "p": "$results.previous_leaf"
22
+ },
23
+ "id": "call_fund"
24
+ }
25
+ ],
26
+ "effects": {
27
+ "moves": [
28
+ {
29
+ "signature": "moves.transfer.internal",
30
+ "source": "fund_piece.call_fund.leaf_fund"
31
+ }
32
+ ]
33
+ },
34
+ "input": {
35
+ "additionalProperties": false,
36
+ "properties": {
37
+ "pieceId": {
38
+ "enum": [
39
+ "p1",
40
+ "p2"
41
+ ],
42
+ "type": "string"
43
+ }
44
+ },
45
+ "required": [
46
+ "pieceId"
47
+ ],
48
+ "type": "object"
49
+ },
50
+ "moves": [],
51
+ "pieceStage": {
52
+ "plan": "split_plan",
53
+ "stage": "fund"
54
+ },
55
+ "steps": [],
56
+ "summary": "Fund one piece in stage"
57
+ },
58
+ "payout_piece": {
59
+ "calls": [
60
+ {
61
+ "action": "transfers.execute_release",
62
+ "bind": {
63
+ "inst": "$instance",
64
+ "p": "$piece"
65
+ },
66
+ "id": "call_rel"
67
+ }
68
+ ],
69
+ "effects": {
70
+ "moves": [
71
+ {
72
+ "signature": "moves.transfer.internal",
73
+ "source": "payout_piece.call_rel.leaf_rel"
74
+ }
75
+ ]
76
+ },
77
+ "input": {
78
+ "additionalProperties": false,
79
+ "properties": {
80
+ "pieceId": {
81
+ "enum": [
82
+ "p1",
83
+ "p2"
84
+ ],
85
+ "type": "string"
86
+ }
87
+ },
88
+ "required": [
89
+ "pieceId"
90
+ ],
91
+ "type": "object"
92
+ },
93
+ "moves": [],
94
+ "pieceStage": {
95
+ "plan": "split_plan",
96
+ "stage": "release"
97
+ },
98
+ "steps": [],
99
+ "summary": "Release piece"
100
+ }
101
+ },
102
+ "actionLibrary": {
103
+ "transfers": {
104
+ "actionOrder": [
105
+ "execute_fund",
106
+ "execute_release"
107
+ ],
108
+ "actions": {
109
+ "execute_fund": {
110
+ "approval": "inherit",
111
+ "calls": [],
112
+ "leaves": [
113
+ {
114
+ "bind": {
115
+ "amount": "$p.amount",
116
+ "destinationAccountId": "$p.release_to",
117
+ "sourceAccountId": "$inst.fields.buyerAccount"
118
+ },
119
+ "effects": [
120
+ {
121
+ "kind": "moves",
122
+ "signature": "moves.transfer.internal"
123
+ }
124
+ ],
125
+ "evidence": "bank transfer confirmation receipt",
126
+ "id": "leaf_fund",
127
+ "operation": "internal_transfer.create"
128
+ }
129
+ ],
130
+ "order": [
131
+ "leaf_fund"
132
+ ],
133
+ "parameters": {
134
+ "inst": {
135
+ "kind": "instance"
136
+ },
137
+ "p": {
138
+ "kind": "piece"
139
+ }
140
+ },
141
+ "principal": "api_key",
142
+ "recovery": "local"
143
+ },
144
+ "execute_release": {
145
+ "approval": "inherit",
146
+ "calls": [],
147
+ "leaves": [
148
+ {
149
+ "bind": {
150
+ "amount": "$p.amount",
151
+ "destinationAccountId": "$p.release_to",
152
+ "sourceAccountId": "$inst.fields.escrowAccount"
153
+ },
154
+ "effects": [
155
+ {
156
+ "kind": "moves",
157
+ "signature": "moves.transfer.internal"
158
+ }
159
+ ],
160
+ "evidence": "release to payee confirmation",
161
+ "id": "leaf_rel",
162
+ "operation": "internal_transfer.create"
163
+ }
164
+ ],
165
+ "order": [
166
+ "leaf_rel"
167
+ ],
168
+ "parameters": {
169
+ "inst": {
170
+ "kind": "instance"
171
+ },
172
+ "p": {
173
+ "kind": "piece"
174
+ }
175
+ },
176
+ "principal": "api_key",
177
+ "recovery": "local"
178
+ }
179
+ }
180
+ }
181
+ },
182
+ "fields": {
183
+ "buyerAccount": {
184
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
185
+ "type": "string"
186
+ },
187
+ "currency": {
188
+ "const": "USD",
189
+ "pattern": "^[A-Z]{3}$",
190
+ "type": "string"
191
+ },
192
+ "escrowAccount": {
193
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
194
+ "type": "string"
195
+ },
196
+ "p1Amount": {
197
+ "pattern": "^[1-9][0-9]{0,17}$",
198
+ "type": "string",
199
+ "x-hyperscale-currency": "USD"
200
+ },
201
+ "p1Refund": {
202
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
203
+ "type": "string"
204
+ },
205
+ "p1Release": {
206
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
207
+ "type": "string"
208
+ },
209
+ "p2Amount": {
210
+ "pattern": "^[1-9][0-9]{0,17}$",
211
+ "type": "string",
212
+ "x-hyperscale-currency": "USD"
213
+ },
214
+ "p2Refund": {
215
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
216
+ "type": "string"
217
+ },
218
+ "p2Release": {
219
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
220
+ "type": "string"
221
+ },
222
+ "totalAmount": {
223
+ "pattern": "^[1-9][0-9]{0,17}$",
224
+ "type": "string",
225
+ "x-hyperscale-currency": "USD"
226
+ }
227
+ },
228
+ "id": "escrow_watch",
229
+ "idPrefix": "ew",
230
+ "lifecycle": {
231
+ "initial": "draft",
232
+ "states": [
233
+ "draft",
234
+ "funded",
235
+ "released"
236
+ ],
237
+ "transitions": {
238
+ "fund_piece": {
239
+ "from": [
240
+ "draft"
241
+ ],
242
+ "to": "funded"
243
+ },
244
+ "payout_piece": {
245
+ "from": [
246
+ "funded"
247
+ ],
248
+ "to": "released"
249
+ }
250
+ }
251
+ },
252
+ "partitions": [
253
+ {
254
+ "pieceFields": [
255
+ "p1Amount",
256
+ "p2Amount"
257
+ ],
258
+ "totalField": "totalAmount"
259
+ }
260
+ ],
261
+ "piecePlan": {
262
+ "fund_order": [
263
+ "p1",
264
+ "p2"
265
+ ],
266
+ "id": "split_plan",
267
+ "pieces": [
268
+ {
269
+ "amount": "p1Amount",
270
+ "id": "p1",
271
+ "refund_to": "p1Refund",
272
+ "release_to": "p1Release"
273
+ },
274
+ {
275
+ "amount": "p2Amount",
276
+ "id": "p2",
277
+ "refund_to": "p2Refund",
278
+ "release_to": "p2Release"
279
+ }
280
+ ],
281
+ "refund_order": [
282
+ "p1"
283
+ ],
284
+ "release_order": [
285
+ "p1",
286
+ "p2"
287
+ ],
288
+ "total": "totalAmount",
289
+ "unfund_order": [
290
+ "p2",
291
+ "p1"
292
+ ]
293
+ },
294
+ "required": [
295
+ "totalAmount",
296
+ "p1Amount",
297
+ "p2Amount",
298
+ "p1Release",
299
+ "p1Refund",
300
+ "p2Release",
301
+ "p2Refund",
302
+ "buyerAccount",
303
+ "escrowAccount"
304
+ ],
305
+ "summary": "Escrow watch contract with piece plan",
306
+ "title": "Escrow Watch"
307
+ }
308
+ ],
309
+ "product": "escrow_watch",
310
+ "subjects": [],
311
+ "title": "Escrow Watch Document",
312
+ "udl": 1,
313
+ "version": 1
314
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "issues": [
3
+ {
4
+ "code": "UDL2010",
5
+ "path": "$.instruments[0].actions.fund_piece.calls.call_fund.action"
6
+ }
7
+ ],
8
+ "summary": "A call names an action the library does not declare.",
9
+ "verdict": "invalid"
10
+ }
@@ -0,0 +1,314 @@
1
+ {
2
+ "instruments": [
3
+ {
4
+ "actionOrder": [
5
+ "create",
6
+ "fund_piece",
7
+ "payout_piece"
8
+ ],
9
+ "actions": {
10
+ "create": {
11
+ "moves": [],
12
+ "steps": [],
13
+ "summary": "Create watch instrument"
14
+ },
15
+ "fund_piece": {
16
+ "calls": [
17
+ {
18
+ "action": "transfers.unknown_action",
19
+ "bind": {
20
+ "inst": "$instance",
21
+ "p": "$piece"
22
+ },
23
+ "id": "call_fund"
24
+ }
25
+ ],
26
+ "effects": {
27
+ "moves": [
28
+ {
29
+ "signature": "moves.transfer.internal",
30
+ "source": "fund_piece.call_fund.leaf_fund"
31
+ }
32
+ ]
33
+ },
34
+ "input": {
35
+ "additionalProperties": false,
36
+ "properties": {
37
+ "pieceId": {
38
+ "enum": [
39
+ "p1",
40
+ "p2"
41
+ ],
42
+ "type": "string"
43
+ }
44
+ },
45
+ "required": [
46
+ "pieceId"
47
+ ],
48
+ "type": "object"
49
+ },
50
+ "moves": [],
51
+ "pieceStage": {
52
+ "plan": "split_plan",
53
+ "stage": "fund"
54
+ },
55
+ "steps": [],
56
+ "summary": "Fund one piece in stage"
57
+ },
58
+ "payout_piece": {
59
+ "calls": [
60
+ {
61
+ "action": "transfers.execute_release",
62
+ "bind": {
63
+ "inst": "$instance",
64
+ "p": "$piece"
65
+ },
66
+ "id": "call_rel"
67
+ }
68
+ ],
69
+ "effects": {
70
+ "moves": [
71
+ {
72
+ "signature": "moves.transfer.internal",
73
+ "source": "payout_piece.call_rel.leaf_rel"
74
+ }
75
+ ]
76
+ },
77
+ "input": {
78
+ "additionalProperties": false,
79
+ "properties": {
80
+ "pieceId": {
81
+ "enum": [
82
+ "p1",
83
+ "p2"
84
+ ],
85
+ "type": "string"
86
+ }
87
+ },
88
+ "required": [
89
+ "pieceId"
90
+ ],
91
+ "type": "object"
92
+ },
93
+ "moves": [],
94
+ "pieceStage": {
95
+ "plan": "split_plan",
96
+ "stage": "release"
97
+ },
98
+ "steps": [],
99
+ "summary": "Release piece"
100
+ }
101
+ },
102
+ "actionLibrary": {
103
+ "transfers": {
104
+ "actionOrder": [
105
+ "execute_fund",
106
+ "execute_release"
107
+ ],
108
+ "actions": {
109
+ "execute_fund": {
110
+ "approval": "inherit",
111
+ "calls": [],
112
+ "leaves": [
113
+ {
114
+ "bind": {
115
+ "amount": "$p.amount",
116
+ "destinationAccountId": "$p.release_to",
117
+ "sourceAccountId": "$inst.fields.buyerAccount"
118
+ },
119
+ "effects": [
120
+ {
121
+ "kind": "moves",
122
+ "signature": "moves.transfer.internal"
123
+ }
124
+ ],
125
+ "evidence": "bank transfer confirmation receipt",
126
+ "id": "leaf_fund",
127
+ "operation": "internal_transfer.create"
128
+ }
129
+ ],
130
+ "order": [
131
+ "leaf_fund"
132
+ ],
133
+ "parameters": {
134
+ "inst": {
135
+ "kind": "instance"
136
+ },
137
+ "p": {
138
+ "kind": "piece"
139
+ }
140
+ },
141
+ "principal": "api_key",
142
+ "recovery": "local"
143
+ },
144
+ "execute_release": {
145
+ "approval": "inherit",
146
+ "calls": [],
147
+ "leaves": [
148
+ {
149
+ "bind": {
150
+ "amount": "$p.amount",
151
+ "destinationAccountId": "$p.release_to",
152
+ "sourceAccountId": "$inst.fields.escrowAccount"
153
+ },
154
+ "effects": [
155
+ {
156
+ "kind": "moves",
157
+ "signature": "moves.transfer.internal"
158
+ }
159
+ ],
160
+ "evidence": "release to payee confirmation",
161
+ "id": "leaf_rel",
162
+ "operation": "internal_transfer.create"
163
+ }
164
+ ],
165
+ "order": [
166
+ "leaf_rel"
167
+ ],
168
+ "parameters": {
169
+ "inst": {
170
+ "kind": "instance"
171
+ },
172
+ "p": {
173
+ "kind": "piece"
174
+ }
175
+ },
176
+ "principal": "api_key",
177
+ "recovery": "local"
178
+ }
179
+ }
180
+ }
181
+ },
182
+ "fields": {
183
+ "buyerAccount": {
184
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
185
+ "type": "string"
186
+ },
187
+ "currency": {
188
+ "const": "USD",
189
+ "pattern": "^[A-Z]{3}$",
190
+ "type": "string"
191
+ },
192
+ "escrowAccount": {
193
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
194
+ "type": "string"
195
+ },
196
+ "p1Amount": {
197
+ "pattern": "^[1-9][0-9]{0,17}$",
198
+ "type": "string",
199
+ "x-hyperscale-currency": "USD"
200
+ },
201
+ "p1Refund": {
202
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
203
+ "type": "string"
204
+ },
205
+ "p1Release": {
206
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
207
+ "type": "string"
208
+ },
209
+ "p2Amount": {
210
+ "pattern": "^[1-9][0-9]{0,17}$",
211
+ "type": "string",
212
+ "x-hyperscale-currency": "USD"
213
+ },
214
+ "p2Refund": {
215
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
216
+ "type": "string"
217
+ },
218
+ "p2Release": {
219
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
220
+ "type": "string"
221
+ },
222
+ "totalAmount": {
223
+ "pattern": "^[1-9][0-9]{0,17}$",
224
+ "type": "string",
225
+ "x-hyperscale-currency": "USD"
226
+ }
227
+ },
228
+ "id": "escrow_watch",
229
+ "idPrefix": "ew",
230
+ "lifecycle": {
231
+ "initial": "draft",
232
+ "states": [
233
+ "draft",
234
+ "funded",
235
+ "released"
236
+ ],
237
+ "transitions": {
238
+ "fund_piece": {
239
+ "from": [
240
+ "draft"
241
+ ],
242
+ "to": "funded"
243
+ },
244
+ "payout_piece": {
245
+ "from": [
246
+ "funded"
247
+ ],
248
+ "to": "released"
249
+ }
250
+ }
251
+ },
252
+ "partitions": [
253
+ {
254
+ "pieceFields": [
255
+ "p1Amount",
256
+ "p2Amount"
257
+ ],
258
+ "totalField": "totalAmount"
259
+ }
260
+ ],
261
+ "piecePlan": {
262
+ "fund_order": [
263
+ "p1",
264
+ "p2"
265
+ ],
266
+ "id": "split_plan",
267
+ "pieces": [
268
+ {
269
+ "amount": "p1Amount",
270
+ "id": "p1",
271
+ "refund_to": "p1Refund",
272
+ "release_to": "p1Release"
273
+ },
274
+ {
275
+ "amount": "p2Amount",
276
+ "id": "p2",
277
+ "refund_to": "p2Refund",
278
+ "release_to": "p2Release"
279
+ }
280
+ ],
281
+ "refund_order": [
282
+ "p1"
283
+ ],
284
+ "release_order": [
285
+ "p1",
286
+ "p2"
287
+ ],
288
+ "total": "totalAmount",
289
+ "unfund_order": [
290
+ "p2",
291
+ "p1"
292
+ ]
293
+ },
294
+ "required": [
295
+ "totalAmount",
296
+ "p1Amount",
297
+ "p2Amount",
298
+ "p1Release",
299
+ "p1Refund",
300
+ "p2Release",
301
+ "p2Refund",
302
+ "buyerAccount",
303
+ "escrowAccount"
304
+ ],
305
+ "summary": "Escrow watch contract with piece plan",
306
+ "title": "Escrow Watch"
307
+ }
308
+ ],
309
+ "product": "escrow_watch",
310
+ "subjects": [],
311
+ "title": "Escrow Watch Document",
312
+ "udl": 1,
313
+ "version": 1
314
+ }