@wowok/agent-mcp 2.6.1 → 2.6.4

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 (246) hide show
  1. package/dist/customer/customer-advice.d.ts +31 -0
  2. package/dist/customer/customer-advice.js +129 -0
  3. package/dist/customer/index.d.ts +2 -0
  4. package/dist/customer/index.js +2 -0
  5. package/dist/customer/info-puzzle.d.ts +9 -2
  6. package/dist/customer/info-puzzle.js +34 -7
  7. package/dist/customer/order-monitor.d.ts +2 -0
  8. package/dist/customer/order-monitor.js +3 -2
  9. package/dist/customer/post-purchase.d.ts +2 -0
  10. package/dist/customer/post-purchase.js +6 -5
  11. package/dist/customer/preorder-compare.d.ts +24 -0
  12. package/dist/customer/preorder-compare.js +34 -0
  13. package/dist/customer/reminder-system.d.ts +2 -0
  14. package/dist/customer/reminder-system.js +2 -1
  15. package/dist/customer/risk-assessment.js +30 -7
  16. package/dist/customer/types.d.ts +7 -0
  17. package/dist/examples/arbitration-dispute-create.json +41 -0
  18. package/dist/examples/arbitration-vote-weighted.json +35 -0
  19. package/dist/examples/arbitration-voting-guard-add.json +38 -0
  20. package/dist/examples/demand-present-service.json +33 -0
  21. package/dist/examples/gen-passport-verify-guard.json +48 -0
  22. package/dist/examples/guard-template-balance-check.json +59 -0
  23. package/dist/examples/guard-template-time-lock.json +60 -0
  24. package/dist/examples/insurance-guard-claim-timelock.json +75 -0
  25. package/dist/examples/insurance-guard-withdraw-allocation.json +96 -0
  26. package/dist/examples/insurance-machine-create-publish.json +75 -0
  27. package/dist/examples/insurance-service-allocators-publish.json +56 -0
  28. package/dist/examples/machine-multisig-threshold.json +86 -0
  29. package/dist/examples/machine-template-7node-rental.json +119 -0
  30. package/dist/examples/payment-scenario-bound.json +45 -0
  31. package/dist/examples/rental-ziroom-machine-create.json +149 -0
  32. package/dist/examples/rental-ziroom-permission-create.json +42 -0
  33. package/dist/examples/rental-ziroom-service-create.json +89 -0
  34. package/dist/examples/retail-adv-guard-customer-win-create.json +80 -0
  35. package/dist/examples/retail-adv-guard-messenger-proof-create.json +65 -0
  36. package/dist/examples/retail-adv-guard-reward-timeout-create.json +92 -0
  37. package/dist/examples/retail-adv-reward-guard-add.json +51 -0
  38. package/dist/examples/retail-myshop-allocation-activate.json +55 -0
  39. package/dist/examples/retail-myshop-arbitration-create.json +40 -0
  40. package/dist/examples/retail-myshop-contact-create.json +43 -0
  41. package/dist/examples/retail-myshop-order-create.json +56 -0
  42. package/dist/examples/retail-myshop-progress-operate.json +38 -0
  43. package/dist/examples/retail-myshop-reward-create.json +35 -0
  44. package/dist/examples/retail-myshop-service-create.json +88 -0
  45. package/dist/examples/service-discount-issue.json +46 -0
  46. package/dist/examples/threebody-guard-create.json +56 -0
  47. package/dist/examples/threebody-machine-create.json +72 -0
  48. package/dist/examples/threebody-permission-create.json +38 -0
  49. package/dist/examples/threebody-service-allocators.json +49 -0
  50. package/dist/examples/travel-guard-time-lock.json +69 -0
  51. package/dist/examples/travel-guard-weather-oracle.json +70 -0
  52. package/dist/examples/travel-machine-create.json +136 -0
  53. package/dist/examples/travel-repository-create.json +47 -0
  54. package/dist/examples/travel-service-create.json +102 -0
  55. package/dist/examples/travel-treasury-create.json +34 -0
  56. package/dist/examples/treasury-deposit.json +37 -0
  57. package/dist/examples/treasury-withdraw.json +38 -0
  58. package/dist/extensions/business-modules.d.ts +49 -0
  59. package/dist/extensions/business-modules.js +287 -0
  60. package/dist/extensions/capability-manifest.js +216 -29
  61. package/dist/extensions/constraint-registry.js +21 -19
  62. package/dist/extensions/metric-registry.js +14 -14
  63. package/dist/extensions/mode-evaluator.js +16 -16
  64. package/dist/extensions/modes.js +141 -49
  65. package/dist/extensions/registry.d.ts +16 -9
  66. package/dist/extensions/registry.js +132 -44
  67. package/dist/extensions/types.d.ts +2 -0
  68. package/dist/index.js +50 -0
  69. package/dist/knowledge/deployment-scanner.js +1 -1
  70. package/dist/knowledge/fund-layer.d.ts +138 -0
  71. package/dist/knowledge/fund-layer.js +969 -0
  72. package/dist/knowledge/guard-render.d.ts +57 -0
  73. package/dist/knowledge/guard-render.js +700 -0
  74. package/dist/knowledge/guard-submission-prompt.d.ts +31 -0
  75. package/dist/knowledge/guard-submission-prompt.js +171 -0
  76. package/dist/knowledge/guard-templates.d.ts +10 -0
  77. package/dist/knowledge/guard-templates.js +50 -0
  78. package/dist/knowledge/index.d.ts +2 -2
  79. package/dist/knowledge/index.js +2 -2
  80. package/dist/knowledge/machine-ledger.js +1 -1
  81. package/dist/knowledge/machine-render.d.ts +41 -0
  82. package/dist/knowledge/machine-render.js +565 -0
  83. package/dist/knowledge/machine-risk.js +4 -1
  84. package/dist/knowledge/machine-templates.js +4 -4
  85. package/dist/knowledge/progress-context.js +1 -1
  86. package/dist/knowledge/progress-ledger.js +3 -3
  87. package/dist/knowledge/progress-templates.js +1 -1
  88. package/dist/knowledge/progress-translation.js +1 -1
  89. package/dist/knowledge/reward-confirm.js +2 -2
  90. package/dist/knowledge/reward-puzzle.js +1 -1
  91. package/dist/knowledge/reward-risk.js +9 -9
  92. package/dist/knowledge/reward-templates.js +2 -2
  93. package/dist/knowledge/safety-rules.d.ts +83 -1
  94. package/dist/knowledge/safety-rules.js +166 -2
  95. package/dist/knowledge/scenario-modes.d.ts +1 -1
  96. package/dist/knowledge/scenario-modes.js +13 -11
  97. package/dist/knowledge/service-confirm.d.ts +1 -1
  98. package/dist/knowledge/service-confirm.js +3 -3
  99. package/dist/knowledge/service-context.js +1 -1
  100. package/dist/knowledge/service-ledger.js +1 -1
  101. package/dist/knowledge/service-risk.d.ts +1 -1
  102. package/dist/knowledge/service-risk.js +3 -3
  103. package/dist/knowledge/service-templates.js +2 -2
  104. package/dist/knowledge/service-translation.d.ts +1 -1
  105. package/dist/knowledge/service-translation.js +7 -7
  106. package/dist/knowledge/template-registry.d.ts +48 -0
  107. package/dist/knowledge/template-registry.js +341 -0
  108. package/dist/knowledge/tool-constraints.js +6 -6
  109. package/dist/knowledge/tools-reference.js +11 -8
  110. package/dist/participation/merchant-interest.d.ts +32 -0
  111. package/dist/participation/merchant-interest.js +100 -0
  112. package/dist/participation/radar-core.d.ts +104 -0
  113. package/dist/participation/radar-core.js +269 -0
  114. package/dist/project/context-assembly.js +8 -0
  115. package/dist/project/deployment-bridge.js +6 -5
  116. package/dist/project/deployment-doc.js +5 -5
  117. package/dist/project/edit-planner.d.ts +123 -0
  118. package/dist/project/edit-planner.js +1342 -0
  119. package/dist/project/evaluation.d.ts +36 -0
  120. package/dist/project/evaluation.js +734 -68
  121. package/dist/project/game-theory.d.ts +43 -0
  122. package/dist/project/game-theory.js +177 -0
  123. package/dist/project/graph-builder.js +7 -1
  124. package/dist/project/handlers.d.ts +137 -2
  125. package/dist/project/handlers.js +423 -51
  126. package/dist/project/intent-analyzer.d.ts +71 -0
  127. package/dist/project/intent-analyzer.js +149 -0
  128. package/dist/project/machine-nodes.d.ts +2 -0
  129. package/dist/project/machine-nodes.js +36 -0
  130. package/dist/project/merchant-guide.d.ts +165 -0
  131. package/dist/project/merchant-guide.js +264 -0
  132. package/dist/project/mode-actions.d.ts +199 -0
  133. package/dist/project/mode-actions.js +309 -0
  134. package/dist/project/participation-radar.d.ts +18 -0
  135. package/dist/project/participation-radar.js +428 -0
  136. package/dist/project/pipeline-actions.d.ts +101 -0
  137. package/dist/project/pipeline-actions.js +109 -0
  138. package/dist/project/semantic-graph.d.ts +95 -0
  139. package/dist/project/semantic-graph.js +245 -0
  140. package/dist/project/stage-gate.js +4 -4
  141. package/dist/schema/call/allocation.d.ts +11 -11
  142. package/dist/schema/call/allocation.js +13 -3
  143. package/dist/schema/call/arbitration.d.ts +21 -21
  144. package/dist/schema/call/arbitration.js +30 -9
  145. package/dist/schema/call/base.d.ts +2 -2
  146. package/dist/schema/call/base.js +1 -1
  147. package/dist/schema/call/bridge.d.ts +127 -127
  148. package/dist/schema/call/bridge.js +12 -12
  149. package/dist/schema/call/contact.d.ts +3 -3
  150. package/dist/schema/call/contact.js +2 -2
  151. package/dist/schema/call/demand.d.ts +3 -3
  152. package/dist/schema/call/demand.js +2 -2
  153. package/dist/schema/call/guard.d.ts +11 -11
  154. package/dist/schema/call/guard.js +2 -2
  155. package/dist/schema/call/machine.d.ts +2072 -679
  156. package/dist/schema/call/machine.js +51 -5
  157. package/dist/schema/call/order.d.ts +7 -7
  158. package/dist/schema/call/order.js +3 -6
  159. package/dist/schema/call/payment.d.ts +3 -3
  160. package/dist/schema/call/permission.d.ts +3 -3
  161. package/dist/schema/call/permission.js +2 -2
  162. package/dist/schema/call/personal.d.ts +337 -3
  163. package/dist/schema/call/personal.js +10 -0
  164. package/dist/schema/call/progress.d.ts +177 -9
  165. package/dist/schema/call/progress.js +7 -3
  166. package/dist/schema/call/proof.d.ts +6 -6
  167. package/dist/schema/call/repository.d.ts +3 -3
  168. package/dist/schema/call/repository.js +2 -2
  169. package/dist/schema/call/reward.d.ts +57 -57
  170. package/dist/schema/call/reward.js +3 -3
  171. package/dist/schema/call/semantic.js +48 -2
  172. package/dist/schema/call/service.d.ts +285 -113
  173. package/dist/schema/call/service.js +92 -28
  174. package/dist/schema/call/treasury.d.ts +57 -57
  175. package/dist/schema/call/treasury.js +3 -3
  176. package/dist/schema/common/index.d.ts +2 -0
  177. package/dist/schema/common/index.js +46 -10
  178. package/dist/schema/local/index.js +5 -1
  179. package/dist/schema/messenger/index.js +4 -1
  180. package/dist/schema/operations.d.ts +1318 -317
  181. package/dist/schema/operations.js +76 -7
  182. package/dist/schema/project/index.d.ts +5662 -164
  183. package/dist/schema/project/index.js +1136 -5
  184. package/dist/schema/query/index.d.ts +580 -19
  185. package/dist/schema/query/index.js +88 -36
  186. package/dist/schema/schema-query/index.d.ts +59 -3
  187. package/dist/schema/schema-query/index.js +45 -6
  188. package/dist/schema/trust/index.d.ts +1012 -6
  189. package/dist/schema/trust/index.js +212 -11
  190. package/dist/schema/utils/node-parser.js +13 -0
  191. package/dist/schema/utils/object-type-utils.d.ts +12 -0
  192. package/dist/schema/utils/object-type-utils.js +35 -0
  193. package/dist/schema/utils/permission-machine-check.d.ts +49 -0
  194. package/dist/schema/utils/permission-machine-check.js +121 -0
  195. package/dist/schema/utils/skills-recommendation.d.ts +2 -0
  196. package/dist/schema/utils/skills-recommendation.js +77 -0
  197. package/dist/schema-query/index.d.ts +17 -1
  198. package/dist/schema-query/index.js +359 -3
  199. package/dist/schemas/account_operation.schema.json +1 -1
  200. package/dist/schemas/bridge_operation.schema.json +14 -7
  201. package/dist/schemas/guard2file.schema.json +2 -0
  202. package/dist/schemas/index.json +1 -1
  203. package/dist/schemas/machineNode2file.schema.json +2 -0
  204. package/dist/schemas/messenger_operation.schema.json +1 -1
  205. package/dist/schemas/onchain_events.output.json +1 -1
  206. package/dist/schemas/onchain_operations.output.json +2820 -0
  207. package/dist/schemas/onchain_operations.schema.json +255 -65
  208. package/dist/schemas/onchain_operations_allocation.schema.json +7 -6
  209. package/dist/schemas/onchain_operations_arbitration.schema.json +14 -10
  210. package/dist/schemas/onchain_operations_contact.schema.json +4 -3
  211. package/dist/schemas/onchain_operations_demand.schema.json +4 -3
  212. package/dist/schemas/onchain_operations_gen_passport.schema.json +4 -2
  213. package/dist/schemas/onchain_operations_gen_proof.schema.json +2 -0
  214. package/dist/schemas/onchain_operations_guard.schema.json +579 -1
  215. package/dist/schemas/onchain_operations_machine.schema.json +5 -4
  216. package/dist/schemas/onchain_operations_order.schema.json +7 -6
  217. package/dist/schemas/onchain_operations_payment.schema.json +2 -1
  218. package/dist/schemas/onchain_operations_permission.schema.json +3 -2
  219. package/dist/schemas/onchain_operations_personal.schema.json +37 -0
  220. package/dist/schemas/onchain_operations_progress.schema.json +91 -4
  221. package/dist/schemas/onchain_operations_proof.schema.json +2 -1
  222. package/dist/schemas/onchain_operations_repository.schema.json +4 -3
  223. package/dist/schemas/onchain_operations_reward.schema.json +7 -6
  224. package/dist/schemas/onchain_operations_service.schema.json +80 -19
  225. package/dist/schemas/onchain_operations_treasury.schema.json +5 -4
  226. package/dist/schemas/onchain_table_data.output.json +1 -1
  227. package/dist/schemas/onchain_table_data.schema.json +10 -9
  228. package/dist/schemas/project_operation.output.json +3318 -57
  229. package/dist/schemas/project_operation.schema.json +728 -4
  230. package/dist/schemas/query_toolkit.output.json +16 -16
  231. package/dist/schemas/query_toolkit.schema.json +40 -3
  232. package/dist/schemas/schema_query.output.json +65 -2
  233. package/dist/schemas/schema_query.schema.json +31 -5
  234. package/dist/schemas/trust_score.output.json +392 -1
  235. package/dist/schemas/trust_score.schema.json +275 -1
  236. package/dist/schemas/wowok_buildin_info.output.json +81 -8
  237. package/dist/schemas/wowok_buildin_info.schema.json +46 -2
  238. package/dist/tools/handlers/onchain.js +636 -6
  239. package/dist/tools/handlers/project.js +71 -2
  240. package/dist/tools/handlers/query.js +117 -2
  241. package/dist/tools/handlers/schema-query.js +65 -1
  242. package/dist/tools/handlers/trust.js +192 -6
  243. package/dist/tools/index.d.ts +8 -0
  244. package/dist/tools/index.js +229 -15
  245. package/dist/tools/wrap.js +194 -15
  246. package/package.json +2 -2
@@ -1,10 +1,286 @@
1
1
  import { readFileSync } from "fs";
2
2
  import { resolve } from "path";
3
- import { CallService, CallMachine, CallProgress, CallGuard, CallArbitration, CallRepository, CallContact, CallTreasury, CallReward, CallAllocation, CallPersonal, CallPayment, CallDemand, CallOrder, gen_passport, CallProof, gen_proof, ResponseData, LocalProject, parseGuardFile, formatGuardParseErrors, transformRewardInput, transformPersonalInput, } from "@wowok/wowok";
3
+ import { CallService, CallMachine, CallProgress, CallGuard, CallArbitration, CallRepository, CallContact, CallTreasury, CallReward, CallAllocation, CallPersonal, CallPayment, CallDemand, CallOrder, gen_passport, CallProof, gen_proof, ResponseData, LocalProject, LocalMark, query_objects, parseGuardFile, formatGuardParseErrors, transformRewardInput, transformPersonalInput, } from "@wowok/wowok";
4
4
  import { OnchainOperationsSchema, strictParse, getEnvConfig, handleCallResult, checkClientSchemaCompatibility, parseMachineNodesFromText, formatNodeErrors as formatMachineNodeErrors, transformSubmission, } from "../../schema/index.js";
5
5
  import { handlePermissionOperations } from "../../schema/call/permission-handler.js";
6
+ import { collectPermissionIndexes, checkPermissionAuthorization, formatPermissionWarning, } from "../../schema/utils/permission-machine-check.js";
6
7
  import { isProjectServiceEnabled, normalize as projectNormalize, } from "../../project/index.js";
8
+ import { getSkillsHintForOnchain } from "../../schema/utils/skills-recommendation.js";
9
+ import { prepareFundOperation, generateSkillsHint as generateFundSkillsHint } from "../../knowledge/fund-layer.js";
10
+ import { generateGuardSubmissionPrompt, formatSubmissionPrompt } from "../../knowledge/guard-submission-prompt.js";
7
11
  import { withHarness } from "../shared.js";
12
+ function formatRecipientLabel(recipient) {
13
+ if (!recipient)
14
+ return "unknown";
15
+ if (typeof recipient === "string")
16
+ return recipient;
17
+ if ("GuardIdentifier" in recipient) {
18
+ return `GuardIdentifier(${recipient.GuardIdentifier})`;
19
+ }
20
+ if ("Entity" in recipient) {
21
+ const addr = recipient.Entity;
22
+ if (typeof addr === "string" && addr.length > 16) {
23
+ return `Entity(${addr.slice(0, 8)}...${addr.slice(-4)})`;
24
+ }
25
+ return `Entity(${addr})`;
26
+ }
27
+ if ("Signer" in recipient) {
28
+ return "Signer (transaction signer)";
29
+ }
30
+ return JSON.stringify(recipient);
31
+ }
32
+ function formatMistAmount(amount) {
33
+ const wowEquivalent = Number(amount) / 1_000_000_000;
34
+ if (wowEquivalent === 0)
35
+ return "0 WOW";
36
+ const wowStr = wowEquivalent.toFixed(9).replace(/\.?0+$/, "");
37
+ return `${wowStr} WOW (${amount.toString()} MIST)`;
38
+ }
39
+ function extractNodesForCheck(data) {
40
+ if (!data?.node)
41
+ return [];
42
+ if (data.node.nodes && Array.isArray(data.node.nodes)) {
43
+ return data.node.nodes;
44
+ }
45
+ return [];
46
+ }
47
+ function resolvePermissionRef(data) {
48
+ if (!data?.object)
49
+ return null;
50
+ if (typeof data.object === "string")
51
+ return null;
52
+ const obj = data.object;
53
+ if (obj.permission) {
54
+ if (typeof obj.permission === "string")
55
+ return obj.permission;
56
+ return null;
57
+ }
58
+ return null;
59
+ }
60
+ async function checkMachinePermissionBeforePublish(data, env) {
61
+ if (data?.publish !== true)
62
+ return "";
63
+ const nodes = extractNodesForCheck(data);
64
+ if (nodes.length === 0)
65
+ return "";
66
+ const collection = collectPermissionIndexes(nodes);
67
+ if (collection.requiredIndexes.length === 0) {
68
+ return "";
69
+ }
70
+ let warning = "";
71
+ if (collection.missingRefs.length > 0) {
72
+ warning += "WARNING: Some forwards have NEITHER permissionIndex nor namedOperator. " +
73
+ "These forwards cannot be executed. Add one or the other:\n";
74
+ for (const ref of collection.missingRefs) {
75
+ warning += ` - Node "${ref.nodeName}", pair prev_node="${ref.prevNode}", forward "${ref.forwardName}"\n`;
76
+ }
77
+ warning += "\n";
78
+ }
79
+ const permRef = resolvePermissionRef(data);
80
+ if (!permRef) {
81
+ if (collection.requiredIndexes.length > 0) {
82
+ warning += "PRE-PUBLISH REMINDER: This Machine uses " + collection.requiredIndexes.length +
83
+ " custom permission index(es): [" + collection.requiredIndexes.join(", ") + "]. " +
84
+ "After creating the Permission object, grant entities for each index via " +
85
+ 'permission.op="add perm by index" BEFORE publishing the Machine. ' +
86
+ "Otherwise, forwards using these indexes will be un-executable.\n";
87
+ }
88
+ return warning;
89
+ }
90
+ let permAddress = permRef;
91
+ if (!permRef.startsWith("0x")) {
92
+ try {
93
+ const mark = await LocalMark.Instance().get(permRef);
94
+ if (mark?.address) {
95
+ permAddress = mark.address;
96
+ }
97
+ else {
98
+ return warning + "PRE-PUBLISH: Could not resolve Permission name '" + permRef +
99
+ "' to an address. Ensure the Permission object exists and is marked. " +
100
+ "Required indexes: [" + collection.requiredIndexes.join(", ") + "]\n";
101
+ }
102
+ }
103
+ catch {
104
+ return warning + "PRE-PUBLISH: Failed to lookup Permission name '" + permRef +
105
+ "'. Required indexes: [" + collection.requiredIndexes.join(", ") + "]\n";
106
+ }
107
+ }
108
+ const network = env?.network ?? "testnet";
109
+ let permData = null;
110
+ try {
111
+ const queryResult = await query_objects({
112
+ objects: [permAddress],
113
+ network: network,
114
+ });
115
+ const permObj = queryResult?.objects?.[0];
116
+ if (permObj) {
117
+ permData = {
118
+ address: permAddress,
119
+ entity_count: permObj.entity_count,
120
+ perm_remark: permObj.perm_remark,
121
+ owner: permObj.owner ?? permObj.builder,
122
+ admin: permObj.admin,
123
+ };
124
+ }
125
+ }
126
+ catch {
127
+ return warning + "PRE-PUBLISH: Failed to query Permission object " + permAddress +
128
+ ". Required indexes: [" + collection.requiredIndexes.join(", ") + "]\n";
129
+ }
130
+ if (!permData) {
131
+ return warning + "PRE-PUBLISH: Permission object " + permAddress +
132
+ " not found on-chain. Required indexes: [" + collection.requiredIndexes.join(", ") + "]\n";
133
+ }
134
+ const report = checkPermissionAuthorization(collection.requiredIndexes, permData);
135
+ if (!report.allAuthorized) {
136
+ warning += formatPermissionWarning(report) + "\n";
137
+ }
138
+ return warning;
139
+ }
140
+ async function detectServiceGuardCircularDependency(data) {
141
+ if (!data || typeof data.object !== "object" || data.object === null)
142
+ return null;
143
+ const orderAllocators = data.order_allocators;
144
+ if (!orderAllocators || typeof orderAllocators !== "object")
145
+ return null;
146
+ const allocators = Array.isArray(orderAllocators.allocators)
147
+ ? orderAllocators.allocators
148
+ : [];
149
+ if (allocators.length === 0)
150
+ return null;
151
+ const unresolvedGuards = [];
152
+ const seen = new Set();
153
+ for (const alloc of allocators) {
154
+ const guardRef = alloc?.guard;
155
+ if (typeof guardRef === "string" && !guardRef.startsWith("0x")) {
156
+ if (seen.has(guardRef))
157
+ continue;
158
+ seen.add(guardRef);
159
+ try {
160
+ const addr = await LocalMark.Instance().get_address(guardRef);
161
+ if (!addr) {
162
+ unresolvedGuards.push(guardRef);
163
+ }
164
+ }
165
+ catch {
166
+ unresolvedGuards.push(guardRef);
167
+ }
168
+ }
169
+ }
170
+ if (unresolvedGuards.length === 0)
171
+ return null;
172
+ const guardList = unresolvedGuards.map(g => `'${g}'`).join(", ");
173
+ const serviceObj = data.object;
174
+ const serviceName = serviceObj.name ?? "<service_name>";
175
+ const recommended_steps = [
176
+ {
177
+ step: 1,
178
+ action: "onchain_operations",
179
+ operation_type: "service",
180
+ params: {
181
+ ...data,
182
+ order_allocators: null,
183
+ publish: false,
184
+ },
185
+ purpose: `Create Service '${serviceName}' WITHOUT order_allocators to establish ` +
186
+ `its LocalMark entry. After this step, the name '${serviceName}' resolves ` +
187
+ `to an on-chain address.`,
188
+ },
189
+ {
190
+ step: 2,
191
+ action: "onchain_operations",
192
+ operation_type: "guard",
193
+ params: unresolvedGuards.map(name => ({
194
+ object: { name, type: "Guard" },
195
+ _hint: `Table items may reference Service '${serviceName}' by name`,
196
+ })),
197
+ purpose: `Create Guard(s) ${guardList}. Their table items can now resolve ` +
198
+ `Service '${serviceName}' by name (LocalMark entry from step 1).`,
199
+ },
200
+ {
201
+ step: 3,
202
+ action: "onchain_operations",
203
+ operation_type: "service",
204
+ params: {
205
+ object: serviceName,
206
+ order_allocators: orderAllocators,
207
+ publish: data.publish ?? true,
208
+ },
209
+ purpose: "Update Service with order_allocators (referencing Guards created in " +
210
+ "step 2) and publish. After publish, order_allocators becomes SDK-LOCKED.",
211
+ },
212
+ ];
213
+ const guideText = `⚠️ Circular dependency detected: Service ↔ Guard\n\n` +
214
+ `Cannot create Service with order_allocators referencing non-existent Guard(s): ${guardList}.\n\n` +
215
+ `Explanation: Guard table items may reference the Service by name, creating a circular ` +
216
+ `dependency: the Service must exist as a LocalMark before the Guard can resolve it, ` +
217
+ `but the Guard must exist before the Service can reference it in order_allocators. ` +
218
+ `The SDK would fail with a BCS serialization error: "Expected valid Address for ` +
219
+ `ValueType.Address, but failed to resolve string: <name>".\n\n` +
220
+ `Recommended steps:\n` +
221
+ recommended_steps
222
+ .map(s => ` Step ${s.step} (${s.operation_type}): ${s.purpose}`)
223
+ .join("\n") +
224
+ `\n\nHint: This is the canonical Service↔Guard circular dependency. The 3-step ` +
225
+ `pattern above is the documented solution (see SCHEMA-03 / P0-01 fix in ` +
226
+ `schema/call/service.ts publish field description).`;
227
+ return {
228
+ content: [{
229
+ type: "text",
230
+ text: guideText,
231
+ }],
232
+ structuredContent: {
233
+ result: {
234
+ type: "error",
235
+ error: `Cannot create Service with order_allocators referencing non-existent Guard(s): ${guardList}. Circular dependency: Service↔Guard.`,
236
+ error_code: "circular_dependency_detected",
237
+ retryable: true,
238
+ recovery_hint: JSON.stringify(recommended_steps),
239
+ related_object: serviceName,
240
+ },
241
+ message: "Circular dependency detected: Service ↔ Guard. See recovery_hint for the 3-step creation pattern.",
242
+ },
243
+ };
244
+ }
245
+ function buildFundBlockResult(fund, operationType) {
246
+ const hasMismatch = fund.matchErrors.length > 0;
247
+ const hasInputErrors = fund.errors.length > 0;
248
+ const title = hasMismatch && hasInputErrors
249
+ ? "FUND OPERATION BLOCKED"
250
+ : hasMismatch
251
+ ? "TOKEN TYPE MISMATCH — operation blocked"
252
+ : "FUND INPUT BLOCKED — operation blocked";
253
+ const errorCode = hasMismatch && hasInputErrors
254
+ ? "fund_blocked"
255
+ : hasMismatch
256
+ ? "token_type_mismatch"
257
+ : "fund_input_error";
258
+ const errorText = `⛔ ${title}\n\n` +
259
+ fund.blockingErrors.map(e => ` • ${e}`).join("\n") +
260
+ `\n\nThe token type of a generic on-chain object (e.g. Treasury<T>, Service<T>) is ` +
261
+ `determined at creation and can NEVER be changed, and monetary input is never ` +
262
+ `processed with unknown token precision. This ${operationType} operation was ` +
263
+ `NOT executed. Fix the errors above and re-issue the operation` +
264
+ (fund.objectTokenType ? ` (object token type: ${fund.objectTokenType})` : "") + ".";
265
+ return {
266
+ content: [{ type: "text", text: errorText }],
267
+ structuredContent: {
268
+ result: {
269
+ type: "error",
270
+ error: fund.blockingErrors.join(" | "),
271
+ error_code: errorCode,
272
+ retryable: true,
273
+ recovery_hint: `Use token type ${fund.objectTokenType ?? "<the object's generic token type>"} for all ` +
274
+ `amounts, coins, and receive records in this ${operationType} operation. ` +
275
+ `Query the object via query_toolkit onchain_objects to confirm its generic ` +
276
+ `token type (type_raw, e.g. "0x2::treasury::Treasury<0x2::wow::WOW>"). ` +
277
+ `For precision-unavailable tokens, retry the operation — the on-chain ` +
278
+ `metadata lookup may have been transient.`,
279
+ },
280
+ message: "Fund operation blocked before execution.",
281
+ },
282
+ };
283
+ }
8
284
  export async function handleOnchainOperations(args) {
9
285
  let validated;
10
286
  let constraintWarnings = [];
@@ -34,12 +310,19 @@ export async function handleOnchainOperations(args) {
34
310
  const rData = ResponseData(result);
35
311
  const created = rData.filter((r) => r.change === "created" && r.object);
36
312
  for (const obj of created) {
313
+ const isService = !!(obj.type_raw && obj.type_raw.includes("service::Service"));
37
314
  await lp.addObject(project.id, {
38
315
  objectAddress: obj.object,
39
316
  objectType: obj.type_raw,
40
- role: "reference",
317
+ role: isService ? "core" : "reference",
41
318
  });
42
319
  }
320
+ if (operationType === "service") {
321
+ const svc = created.find((o) => o.type_raw && o.type_raw.includes("service::Service"));
322
+ if (svc && svc.object) {
323
+ await lp.updateProject(project.id, { serviceAddress: svc.object }).catch(() => { });
324
+ }
325
+ }
43
326
  }
44
327
  catch {
45
328
  }
@@ -95,13 +378,99 @@ export async function handleOnchainOperations(args) {
95
378
  delete env.project;
96
379
  delete env.client_schema_version;
97
380
  delete env.schema_strict_mode;
381
+ const skillsHint = getSkillsHintForOnchain(validated.operation_type, validated.data);
382
+ if (skillsHint) {
383
+ constraintWarnings.push(skillsHint);
384
+ }
98
385
  switch (validated.operation_type) {
99
386
  case "service": {
100
- const callService = new CallService(validated.data);
101
- const result = validated.submission
102
- ? await callService.call_with_submission(env, await transformSubmission(validated.submission))
103
- : await callService.call(env);
104
387
  const data = validated.data;
388
+ const circularDepGuide = await detectServiceGuardCircularDependency(data);
389
+ if (circularDepGuide) {
390
+ return circularDepGuide;
391
+ }
392
+ const fundResult = await prepareFundOperation(data, "service", env?.network);
393
+ if (fundResult.blockingErrors.length > 0) {
394
+ return buildFundBlockResult(fundResult, "service");
395
+ }
396
+ constraintWarnings.push(...fundResult.warnings);
397
+ if (fundResult.confirmation) {
398
+ constraintWarnings.push(fundResult.confirmation.message);
399
+ const fundHint = generateFundSkillsHint(fundResult.confirmation);
400
+ if (fundHint)
401
+ constraintWarnings.push(fundHint);
402
+ }
403
+ const orderAllocators = data?.order_allocators;
404
+ if (orderAllocators && typeof orderAllocators === "object") {
405
+ const allocators = Array.isArray(orderAllocators.allocators)
406
+ ? orderAllocators.allocators : [];
407
+ for (let i = 0; i < allocators.length; i++) {
408
+ const alloc = allocators[i];
409
+ const sharing = Array.isArray(alloc?.sharing) ? alloc.sharing : [];
410
+ if (sharing.length <= 1)
411
+ continue;
412
+ const seen = new Map();
413
+ for (let j = 0; j < sharing.length; j++) {
414
+ const who = sharing[j]?.who;
415
+ let key = "";
416
+ if (typeof who === "string") {
417
+ key = who;
418
+ }
419
+ else if (who && typeof who === "object") {
420
+ if (who.Entity && typeof who.Entity === "object") {
421
+ key = "Entity:" + (who.Entity.name_or_address ?? "");
422
+ }
423
+ else if (who.Signer) {
424
+ key = "Signer";
425
+ }
426
+ else if (who.GuardIdentifier !== undefined) {
427
+ key = "Guard:" + who.GuardIdentifier;
428
+ }
429
+ else {
430
+ key = JSON.stringify(who);
431
+ }
432
+ }
433
+ if (!key)
434
+ continue;
435
+ const count = seen.get(key) ?? 0;
436
+ seen.set(key, count + 1);
437
+ }
438
+ for (const [key, count] of seen) {
439
+ if (count > 1) {
440
+ constraintWarnings.push(`DUPLICATE SHARING ENTITY: Allocator[${i}] has entity "${key}" appearing ${count} times ` +
441
+ `in the sharing array. This is likely a configuration error — each entity should appear ` +
442
+ `at most once per allocator. Total sharing: ${count * 100}% to the same entity. ` +
443
+ `If intentional, ignore this warning.`);
444
+ }
445
+ }
446
+ }
447
+ }
448
+ const callService = new CallService(validated.data);
449
+ let result;
450
+ try {
451
+ result = validated.submission
452
+ ? await callService.call_with_submission(env, await transformSubmission(validated.submission))
453
+ : await callService.call(env);
454
+ }
455
+ catch (e) {
456
+ const errMsg = e.message ?? String(e);
457
+ if (/not found|GetObjectExisted|resolve|LocalMark|failed to resolve/i.test(errMsg)) {
458
+ const permRef = (typeof data?.object === 'object' && data?.object !== null)
459
+ ? data.object.permission
460
+ : undefined;
461
+ throw new Error(`DEPENDENCY RESOLUTION FAILED: One or more referenced objects could not be resolved.\n` +
462
+ `Original error: ${errMsg}\n` +
463
+ `Common causes:\n` +
464
+ ` 1. Object name typo — check spelling in LocalMark\n` +
465
+ ` 2. Object not yet created — create dependencies first\n` +
466
+ ` 3. Object on different network — check env.network\n` +
467
+ `Referenced objects in this call: machine=${data?.machine ?? "<none>"}, ` +
468
+ `buy_guard=${data?.buy_guard ?? "<none>"}, ` +
469
+ `permission=${permRef ?? "<inline/new>"}, ` +
470
+ `arbitrations=${Array.isArray(data?.arbitrations) ? data.arbitrations.length + " item(s)" : "<none>"}`);
471
+ }
472
+ throw e;
473
+ }
105
474
  const intent = data?.publish ? "publish service" : data?.bPublished !== undefined ? "modify service" : "create service";
106
475
  const isCreatingService = data?.object != null && typeof data.object === "object";
107
476
  const hasCompensationFundAdd = data?.compensation_fund_add != null;
@@ -112,6 +481,30 @@ export async function handleOnchainOperations(args) {
112
481
  "from this Service. (Note: some industries like freelance do not require this; " +
113
482
  "the evaluation engine will check industry-specific requirements.)");
114
483
  }
484
+ const isPublishing = data?.publish === true;
485
+ const hasArbitrations = Array.isArray(data?.arbitrations) && data.arbitrations.length > 0;
486
+ if (isPublishing && !hasArbitrations && hasCompensationFundAdd) {
487
+ throw new Error("HARD PRE-CHECK FAILED: Cannot publish Service with compensation_fund > 0 but no Arbitration bound.\n" +
488
+ "Contract (service.move:494): assert!(arbitration_count > 0, E_ARBITRATION_NOT_SET_WITH_COMPENSATION_FUND).\n" +
489
+ "The transaction WILL ABORT on-chain if you proceed.\n" +
490
+ "Fix: (1) Create an Arbitration object first (onchain_operations with operation_type='arbitration').\n" +
491
+ " (2) Set data.arbitrations=[<arbitration_name_or_id>] in this same call.\n" +
492
+ " (3) Then call publish=true.\n" +
493
+ "Note: After publish, arbitrations can still be ADDED (but not removed without pause+lock).");
494
+ }
495
+ if (isPublishing && !hasArbitrations && !hasCompensationFundAdd) {
496
+ constraintWarnings.push("WARNING: Publishing Service without arbitrations. If compensation_fund was " +
497
+ "deposited in a prior call, the contract (service.move:494) WILL ABORT with " +
498
+ "E_ARBITRATION_NOT_SET_WITH_COMPENSATION_FUND. If compensation_fund is 0, " +
499
+ "publish will succeed but buyers have no dispute resolution path. " +
500
+ "Recommended: bind arbitrations before publish.");
501
+ }
502
+ if (!isPublishing && hasCompensationFundAdd && !hasArbitrations) {
503
+ constraintWarnings.push("WARNING: Depositing compensation_fund on a Service without arbitrations bound. " +
504
+ "If this Service is already published, arbitration rulings will not be able to " +
505
+ "withdraw compensation from this Service. Recommended: bind arbitrations first, " +
506
+ "then deposit compensation_fund.");
507
+ }
115
508
  const output = handleCallResult(result, withHarness(buildCtx(data), "service", intent));
116
509
  autoAddToProject(projectEnvPrefix, validated.operation_type, result).catch(() => { });
117
510
  return output;
@@ -141,6 +534,33 @@ export async function handleOnchainOperations(args) {
141
534
  bReplace: true
142
535
  };
143
536
  }
537
+ const machineData = validated.data;
538
+ const permWarning = await checkMachinePermissionBeforePublish(machineData, env);
539
+ if (permWarning) {
540
+ constraintWarnings.push(permWarning);
541
+ }
542
+ const machineNodes = machineData?.node?.nodes ?? machineData?.node;
543
+ if (Array.isArray(machineNodes)) {
544
+ const arbPatterns = /^(dispute|disputed|arbitration|arb_|arb\.|resolve_dispute|start_arbitration|open_dispute)/i;
545
+ for (const node of machineNodes) {
546
+ const nodeName = typeof node === 'object' ? node?.name : '';
547
+ if (typeof nodeName === 'string' && arbPatterns.test(nodeName)) {
548
+ constraintWarnings.push(`ARBITRATION SEPARATION WARNING: Machine node "${nodeName}" appears to be an arbitration-related node.\n` +
549
+ `CORE PRINCIPLE: A merchant cannot handle disputes fairly — they would be 'both player and referee'.\n` +
550
+ `The WoWok smart contract design makes Arbitration a completely separate object:\n` +
551
+ ` - Arbitration has its own Permission, voting_guard, usage_guard, and balance\n` +
552
+ ` - Arb instances have a 7-state lifecycle managed by Arbitration, not by Machine\n` +
553
+ ` - The Order object is the bridge: it has 'progress' (Machine) and 'dispute' (Arb list) fields\n` +
554
+ ` - When Arb rules, it calls order::compensate() — the ONLY connection to the business flow\n\n` +
555
+ `CORRECT PATTERN:\n` +
556
+ ` - Machine: business states only (ordered -> shipped -> delivered -> completed)\n` +
557
+ ` - Arbitration: separate object with its own Permission (NOT shared with Service)\n` +
558
+ ` - Arb: 7-state lifecycle (Principal_confirming -> Arbitrator_confirming -> Voting -> Arbitrated -> Objectionable -> Finished -> Withdrawn)\n` +
559
+ ` - R-M1-11: NEVER name nodes 'refunded'/'disputed'/'arb'/'refund' — use business states ('cancelled'/'returned') for dispute OUTCOMES; refunds route via Allocator triggered by those states, disputes via the separate Arbitration object\n\n` +
560
+ `If this node name is a legitimate business state (not arbitration), ignore this warning.`);
561
+ }
562
+ }
563
+ }
144
564
  const callMachine = new CallMachine(validated.data);
145
565
  const result = validated.submission
146
566
  ? await callMachine.call_with_submission(env, await transformSubmission(validated.submission))
@@ -161,6 +581,65 @@ export async function handleOnchainOperations(args) {
161
581
  const result = validated.submission
162
582
  ? await callProgress.call_with_submission(env, await transformSubmission(validated.submission))
163
583
  : await callProgress.call(env);
584
+ if (!validated.submission && result && typeof result === 'object' && 'submission' in result) {
585
+ const submissionData = result.submission;
586
+ if (Array.isArray(submissionData) && submissionData.length > 0) {
587
+ const guardRef = submissionData[0]?.guard;
588
+ if (guardRef) {
589
+ const submissionCtx = {
590
+ operation: "progress_next",
591
+ network: env?.network,
592
+ signer: env?.account,
593
+ progress_address: validated.data?.object,
594
+ order_address: validated.data?.task,
595
+ };
596
+ const prompt = await generateGuardSubmissionPrompt(guardRef, submissionCtx);
597
+ if (prompt) {
598
+ constraintWarnings.push(formatSubmissionPrompt(prompt));
599
+ }
600
+ }
601
+ }
602
+ }
603
+ if (result && typeof result === 'object' && 'digest' in result
604
+ && result?.effects?.status?.status === 'success') {
605
+ try {
606
+ const progressRef = validated.data?.object;
607
+ let progressAddr;
608
+ if (typeof progressRef === 'string') {
609
+ if (progressRef.startsWith('0x')) {
610
+ progressAddr = progressRef;
611
+ }
612
+ else {
613
+ progressAddr = await LocalMark.Instance().get_address(progressRef) ?? undefined;
614
+ }
615
+ }
616
+ if (progressAddr) {
617
+ const progressQuery = await query_objects({
618
+ objects: [progressAddr],
619
+ no_cache: true,
620
+ network: env?.network,
621
+ });
622
+ const progressObj = progressQuery?.objects?.[0];
623
+ if (progressObj?.type === "Progress") {
624
+ const currentNode = progressObj.current ?? "<unknown>";
625
+ const historyCount = Array.isArray(progressObj.session)
626
+ ? progressObj.session.length : 0;
627
+ const machineAddr = progressObj.machine;
628
+ const previewLines = [
629
+ `PROGRESS PREVIEW:`,
630
+ ` • current node: "${currentNode}"`,
631
+ ` • history count: ${historyCount} session(s)`,
632
+ ];
633
+ if (machineAddr) {
634
+ previewLines.push(` • machine: ${machineAddr}`);
635
+ }
636
+ constraintWarnings.push(previewLines.join("\n"));
637
+ }
638
+ }
639
+ }
640
+ catch {
641
+ }
642
+ }
164
643
  const output = handleCallResult(result, buildCtx(validated.data));
165
644
  autoAddToProject(projectEnvPrefix, validated.operation_type, result).catch(() => { });
166
645
  return output;
@@ -175,6 +654,17 @@ export async function handleOnchainOperations(args) {
175
654
  return output;
176
655
  }
177
656
  case "arbitration": {
657
+ const arbFundResult = await prepareFundOperation(validated.data, "arbitration", env?.network);
658
+ if (arbFundResult.blockingErrors.length > 0) {
659
+ return buildFundBlockResult(arbFundResult, "arbitration");
660
+ }
661
+ constraintWarnings.push(...arbFundResult.warnings);
662
+ if (arbFundResult.confirmation) {
663
+ constraintWarnings.push(arbFundResult.confirmation.message);
664
+ const fundHint = generateFundSkillsHint(arbFundResult.confirmation);
665
+ if (fundHint)
666
+ constraintWarnings.push(fundHint);
667
+ }
178
668
  const callArbitration = new CallArbitration(validated.data);
179
669
  const result = validated.submission
180
670
  ? await callArbitration.call_with_submission(env, await transformSubmission(validated.submission))
@@ -193,6 +683,17 @@ export async function handleOnchainOperations(args) {
193
683
  return output;
194
684
  }
195
685
  case "treasury": {
686
+ const trFundResult = await prepareFundOperation(validated.data, "treasury", env?.network);
687
+ if (trFundResult.blockingErrors.length > 0) {
688
+ return buildFundBlockResult(trFundResult, "treasury");
689
+ }
690
+ constraintWarnings.push(...trFundResult.warnings);
691
+ if (trFundResult.confirmation) {
692
+ constraintWarnings.push(trFundResult.confirmation.message);
693
+ const fundHint = generateFundSkillsHint(trFundResult.confirmation);
694
+ if (fundHint)
695
+ constraintWarnings.push(fundHint);
696
+ }
196
697
  const callTreasury = new CallTreasury(validated.data);
197
698
  const result = validated.submission
198
699
  ? await callTreasury.call_with_submission(env, await transformSubmission(validated.submission))
@@ -202,6 +703,17 @@ export async function handleOnchainOperations(args) {
202
703
  return output;
203
704
  }
204
705
  case "reward": {
706
+ const rwFundResult = await prepareFundOperation(validated.data, "reward", env?.network);
707
+ if (rwFundResult.blockingErrors.length > 0) {
708
+ return buildFundBlockResult(rwFundResult, "reward");
709
+ }
710
+ constraintWarnings.push(...rwFundResult.warnings);
711
+ if (rwFundResult.confirmation) {
712
+ constraintWarnings.push(rwFundResult.confirmation.message);
713
+ const fundHint = generateFundSkillsHint(rwFundResult.confirmation);
714
+ if (fundHint)
715
+ constraintWarnings.push(fundHint);
716
+ }
205
717
  const transformedData = transformRewardInput(validated.data);
206
718
  const callReward = new CallReward(transformedData);
207
719
  const result = validated.submission
@@ -212,10 +724,66 @@ export async function handleOnchainOperations(args) {
212
724
  return output;
213
725
  }
214
726
  case "allocation": {
727
+ const alFundResult = await prepareFundOperation(validated.data, "allocation", env?.network);
728
+ if (alFundResult.blockingErrors.length > 0) {
729
+ return buildFundBlockResult(alFundResult, "allocation");
730
+ }
731
+ constraintWarnings.push(...alFundResult.warnings);
732
+ if (alFundResult.confirmation) {
733
+ constraintWarnings.push(alFundResult.confirmation.message);
734
+ const fundHint = generateFundSkillsHint(alFundResult.confirmation);
735
+ if (fundHint)
736
+ constraintWarnings.push(fundHint);
737
+ }
215
738
  const callAllocation = new CallAllocation(validated.data);
216
739
  const result = validated.submission
217
740
  ? await callAllocation.call_with_submission(env, await transformSubmission(validated.submission))
218
741
  : await callAllocation.call(env);
742
+ const allocData = validated.data;
743
+ if (allocData?.alloc_by_guard) {
744
+ const createdPayments = ResponseData(result).filter((e) => e?.type === "Payment" && e?.change === "created");
745
+ if (createdPayments.length > 0) {
746
+ const paymentAddrs = createdPayments.map((p) => p.object).join(", ");
747
+ try {
748
+ const paymentResult = await query_objects({
749
+ objects: createdPayments.map((p) => p.object),
750
+ no_cache: true,
751
+ network: env?.network,
752
+ });
753
+ const distributionLines = [];
754
+ let totalDistributed = BigInt(0);
755
+ for (const obj of paymentResult?.objects || []) {
756
+ if (obj?.type === "Payment" && obj?.record) {
757
+ for (const entry of obj.record) {
758
+ const recipientLabel = formatRecipientLabel(entry.recipient);
759
+ const amountStr = typeof entry.amount === 'string' ? entry.amount : String(entry.amount);
760
+ const amountBig = BigInt(amountStr);
761
+ totalDistributed += amountBig;
762
+ distributionLines.push(` • ${recipientLabel}: ${formatMistAmount(amountBig)}`);
763
+ }
764
+ if (obj.object) {
765
+ distributionLines.push(` • Payment object: ${obj.object}`);
766
+ }
767
+ }
768
+ }
769
+ if (distributionLines.length > 0) {
770
+ distributionLines.unshift(`DISTRIBUTION DETAILS (alloc_by_guard):`);
771
+ distributionLines.push(` ─────────────────`, ` • Total distributed: ${formatMistAmount(totalDistributed)}`);
772
+ const isEscrow = paymentResult?.objects?.some((obj) => obj?.type === "Payment" && obj?.info?.for_object);
773
+ if (isEscrow) {
774
+ distributionLines.push(``, `ESCROW MODE: Funds are held in escrow (Payment.for_object points to an Order). ` +
775
+ `The Order owner must call order_claim (or service_order_claim) to actually receive the funds. ` +
776
+ `This happens when the Guard's sharing config uses { GuardIdentifier: 0 }.`);
777
+ }
778
+ constraintWarnings.push(distributionLines.join("\n"));
779
+ }
780
+ }
781
+ catch {
782
+ constraintWarnings.push(`alloc_by_guard created Payment object(s) [${paymentAddrs}]. ` +
783
+ `Query these Payment objects to see the distribution details and check for_object for escrow mode.`);
784
+ }
785
+ }
786
+ }
219
787
  const output = handleCallResult(result, buildCtx(validated.data));
220
788
  autoAddToProject(projectEnvPrefix, validated.operation_type, result).catch(() => { });
221
789
  return output;
@@ -277,6 +845,34 @@ export async function handleOnchainOperations(args) {
277
845
  }
278
846
  const callGuard = new CallGuard(validatedData);
279
847
  const result = await callGuard.call(env);
848
+ if (result && typeof result === 'object' && 'digest' in result
849
+ && result?.effects?.status?.status === 'success') {
850
+ try {
851
+ const rootType = validatedData.root?.type ?? "<unknown>";
852
+ const tableArr = Array.isArray(validatedData.table) ? validatedData.table : [];
853
+ const tableEntries = tableArr.length;
854
+ const submissionEntries = tableArr.filter((t) => t?.b_submission === true).length;
855
+ const relyGuards = validatedData.rely?.guards;
856
+ const relyCount = Array.isArray(relyGuards) ? relyGuards.length : 0;
857
+ const relyMode = validatedData.rely?.logic_or === true
858
+ ? "OR" : validatedData.rely?.logic_or === false ? "AND" : "none";
859
+ const summaryLines = [
860
+ `GUARD LOGIC SUMMARY:`,
861
+ ` • root type: ${rootType}`,
862
+ ` • table entries: ${tableEntries} (${submissionEntries} require runtime submission)`,
863
+ ];
864
+ if (relyCount > 0) {
865
+ summaryLines.push(` • relies on: ${relyCount} guard(s) (mode: ${relyMode})`);
866
+ }
867
+ if (validatedData.description) {
868
+ const desc = String(validatedData.description).slice(0, 80);
869
+ summaryLines.push(` • description: "${desc}"`);
870
+ }
871
+ constraintWarnings.push(summaryLines.join("\n"));
872
+ }
873
+ catch {
874
+ }
875
+ }
280
876
  const output = handleCallResult(result, buildCtx(validated.data));
281
877
  autoAddToProject(projectEnvPrefix, validated.operation_type, result).catch(() => { });
282
878
  return output;
@@ -290,6 +886,40 @@ export async function handleOnchainOperations(args) {
290
886
  return output;
291
887
  }
292
888
  case "payment": {
889
+ const payFundResult = await prepareFundOperation(validated.data, "payment", env?.network);
890
+ if (payFundResult.blockingErrors.length > 0) {
891
+ return buildFundBlockResult(payFundResult, "payment");
892
+ }
893
+ constraintWarnings.push(...payFundResult.warnings);
894
+ if (payFundResult.confirmation) {
895
+ constraintWarnings.push(payFundResult.confirmation.message);
896
+ const fundHint = generateFundSkillsHint(payFundResult.confirmation);
897
+ if (fundHint)
898
+ constraintWarnings.push(fundHint);
899
+ }
900
+ const paymentData = validated.data;
901
+ if (paymentData?.receive === true) {
902
+ constraintWarnings.push("RECEIVE MODE (order_claim): You are unwrapping a CoinWrapper to your wallet. " +
903
+ "This is the final step of the escrow flow:\n" +
904
+ " 1. Allocation's alloc_by_guard created a Payment object with your address as a recipient\n" +
905
+ " 2. The Payment's revenue split transferred a CoinWrapper to your wallet (owned but not spendable)\n" +
906
+ " 3. THIS operation unwraps the CoinWrapper via payment::unwrap_to_myself, deleting the " +
907
+ "CoinWrapper and transferring the underlying coin to tx_context::sender\n" +
908
+ "Requirements:\n" +
909
+ " - You MUST be the CoinWrapper's owner (the recipient specified in the Allocation)\n" +
910
+ " - type_parameter MUST match the coin type used when the Allocation created the Payment " +
911
+ "(e.g. '0x2::wow::WOW')\n" +
912
+ " - object can be a CoinWrapper ID (0x...) or a local mark name\n" +
913
+ "To find received CoinWrappers: call query_toolkit with query_type='onchain_received' " +
914
+ "and type='CoinWrapper' for your account.\n" +
915
+ "After success: verify your balance increased via account_balance query.");
916
+ }
917
+ else if (paymentData?.revenue) {
918
+ constraintWarnings.push("CREATE MODE: Creating a new Payment object. Payments are IMMUTABLE after creation — " +
919
+ "they cannot be modified. The 'revenue' array defines the recipients and amounts; " +
920
+ "ensure correctness before submitting. The 'info.for_guard' field (if set) binds this " +
921
+ "Payment to a Guard for conditional release (common in escrow workflows).");
922
+ }
293
923
  const callPayment = new CallPayment(validated.data);
294
924
  const result = await callPayment.call(env);
295
925
  const output = handleCallResult(result, buildCtx(validated.data));