@wowok/agent-mcp 2.6.3 → 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 (192) 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 +8 -1
  6. package/dist/customer/info-puzzle.js +30 -5
  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 +4 -3
  16. package/dist/customer/types.d.ts +5 -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 +36 -15
  23. package/dist/examples/guard-template-time-lock.json +33 -12
  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 +99 -94
  30. package/dist/examples/payment-scenario-bound.json +45 -0
  31. package/dist/examples/rental-ziroom-machine-create.json +126 -114
  32. package/dist/examples/rental-ziroom-permission-create.json +10 -3
  33. package/dist/examples/rental-ziroom-service-create.json +27 -18
  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/service-discount-issue.json +46 -0
  45. package/dist/examples/threebody-guard-create.json +56 -0
  46. package/dist/examples/threebody-machine-create.json +72 -0
  47. package/dist/examples/threebody-permission-create.json +38 -0
  48. package/dist/examples/threebody-service-allocators.json +49 -0
  49. package/dist/examples/travel-guard-time-lock.json +69 -0
  50. package/dist/examples/travel-guard-weather-oracle.json +70 -0
  51. package/dist/examples/travel-machine-create.json +136 -0
  52. package/dist/examples/travel-repository-create.json +47 -0
  53. package/dist/examples/travel-service-create.json +102 -0
  54. package/dist/examples/travel-treasury-create.json +34 -0
  55. package/dist/examples/treasury-deposit.json +37 -0
  56. package/dist/examples/treasury-withdraw.json +38 -0
  57. package/dist/extensions/business-modules.d.ts +49 -0
  58. package/dist/extensions/business-modules.js +287 -0
  59. package/dist/extensions/capability-manifest.js +192 -5
  60. package/dist/extensions/constraint-registry.js +3 -1
  61. package/dist/extensions/modes.js +10 -4
  62. package/dist/extensions/registry.d.ts +14 -9
  63. package/dist/extensions/registry.js +69 -14
  64. package/dist/extensions/types.d.ts +1 -0
  65. package/dist/knowledge/fund-layer.d.ts +67 -1
  66. package/dist/knowledge/fund-layer.js +561 -12
  67. package/dist/knowledge/guard-templates.d.ts +10 -0
  68. package/dist/knowledge/guard-templates.js +50 -0
  69. package/dist/knowledge/index.d.ts +2 -2
  70. package/dist/knowledge/index.js +2 -2
  71. package/dist/knowledge/machine-risk.js +4 -1
  72. package/dist/knowledge/progress-context.js +1 -1
  73. package/dist/knowledge/progress-ledger.js +3 -3
  74. package/dist/knowledge/progress-templates.js +1 -1
  75. package/dist/knowledge/progress-translation.js +1 -1
  76. package/dist/knowledge/safety-rules.d.ts +83 -1
  77. package/dist/knowledge/safety-rules.js +166 -2
  78. package/dist/knowledge/scenario-modes.d.ts +1 -1
  79. package/dist/knowledge/scenario-modes.js +13 -11
  80. package/dist/knowledge/template-registry.d.ts +48 -0
  81. package/dist/knowledge/template-registry.js +341 -0
  82. package/dist/knowledge/tool-constraints.js +6 -6
  83. package/dist/knowledge/tools-reference.js +11 -8
  84. package/dist/participation/merchant-interest.d.ts +32 -0
  85. package/dist/participation/merchant-interest.js +100 -0
  86. package/dist/participation/radar-core.d.ts +104 -0
  87. package/dist/participation/radar-core.js +269 -0
  88. package/dist/project/context-assembly.js +8 -0
  89. package/dist/project/edit-planner.js +27 -56
  90. package/dist/project/evaluation.d.ts +36 -0
  91. package/dist/project/evaluation.js +422 -56
  92. package/dist/project/game-theory.d.ts +43 -0
  93. package/dist/project/game-theory.js +177 -0
  94. package/dist/project/graph-builder.js +1 -0
  95. package/dist/project/handlers.d.ts +38 -0
  96. package/dist/project/handlers.js +65 -35
  97. package/dist/project/intent-analyzer.d.ts +71 -0
  98. package/dist/project/intent-analyzer.js +149 -0
  99. package/dist/project/machine-nodes.d.ts +2 -0
  100. package/dist/project/machine-nodes.js +36 -0
  101. package/dist/project/merchant-guide.d.ts +165 -0
  102. package/dist/project/merchant-guide.js +264 -0
  103. package/dist/project/mode-actions.d.ts +199 -0
  104. package/dist/project/mode-actions.js +309 -0
  105. package/dist/project/participation-radar.d.ts +18 -0
  106. package/dist/project/participation-radar.js +428 -0
  107. package/dist/project/pipeline-actions.d.ts +101 -0
  108. package/dist/project/pipeline-actions.js +109 -0
  109. package/dist/project/semantic-graph.d.ts +95 -0
  110. package/dist/project/semantic-graph.js +245 -0
  111. package/dist/schema/call/allocation.d.ts +11 -11
  112. package/dist/schema/call/allocation.js +11 -1
  113. package/dist/schema/call/arbitration.d.ts +21 -21
  114. package/dist/schema/call/arbitration.js +17 -9
  115. package/dist/schema/call/base.d.ts +2 -2
  116. package/dist/schema/call/base.js +1 -1
  117. package/dist/schema/call/bridge.d.ts +127 -127
  118. package/dist/schema/call/bridge.js +12 -12
  119. package/dist/schema/call/contact.d.ts +3 -3
  120. package/dist/schema/call/demand.d.ts +3 -3
  121. package/dist/schema/call/guard.d.ts +11 -11
  122. package/dist/schema/call/guard.js +1 -1
  123. package/dist/schema/call/machine.d.ts +216 -21
  124. package/dist/schema/call/machine.js +1 -1
  125. package/dist/schema/call/order.d.ts +7 -7
  126. package/dist/schema/call/payment.d.ts +3 -3
  127. package/dist/schema/call/permission.d.ts +3 -3
  128. package/dist/schema/call/personal.d.ts +337 -3
  129. package/dist/schema/call/personal.js +10 -0
  130. package/dist/schema/call/progress.d.ts +177 -9
  131. package/dist/schema/call/progress.js +7 -3
  132. package/dist/schema/call/proof.d.ts +6 -6
  133. package/dist/schema/call/repository.d.ts +3 -3
  134. package/dist/schema/call/reward.d.ts +57 -57
  135. package/dist/schema/call/semantic.js +41 -1
  136. package/dist/schema/call/service.d.ts +114 -114
  137. package/dist/schema/call/service.js +11 -2
  138. package/dist/schema/call/treasury.d.ts +57 -57
  139. package/dist/schema/messenger/index.js +4 -1
  140. package/dist/schema/operations.d.ts +713 -291
  141. package/dist/schema/operations.js +33 -0
  142. package/dist/schema/project/index.d.ts +4635 -100
  143. package/dist/schema/project/index.js +868 -1
  144. package/dist/schema/query/index.d.ts +363 -19
  145. package/dist/schema/query/index.js +25 -3
  146. package/dist/schema/schema-query/index.d.ts +13 -7
  147. package/dist/schema/schema-query/index.js +29 -5
  148. package/dist/schema/trust/index.d.ts +1012 -6
  149. package/dist/schema/trust/index.js +212 -11
  150. package/dist/schema/utils/skills-recommendation.js +1 -0
  151. package/dist/schema-query/index.d.ts +4 -1
  152. package/dist/schema-query/index.js +255 -1
  153. package/dist/schemas/bridge_operation.schema.json +14 -7
  154. package/dist/schemas/guard2file.schema.json +2 -0
  155. package/dist/schemas/index.json +1 -1
  156. package/dist/schemas/machineNode2file.schema.json +2 -0
  157. package/dist/schemas/messenger_operation.schema.json +1 -1
  158. package/dist/schemas/onchain_operations.schema.json +143 -15
  159. package/dist/schemas/onchain_operations_allocation.schema.json +2 -1
  160. package/dist/schemas/onchain_operations_arbitration.schema.json +7 -5
  161. package/dist/schemas/onchain_operations_contact.schema.json +1 -0
  162. package/dist/schemas/onchain_operations_demand.schema.json +1 -0
  163. package/dist/schemas/onchain_operations_gen_passport.schema.json +2 -0
  164. package/dist/schemas/onchain_operations_gen_proof.schema.json +2 -0
  165. package/dist/schemas/onchain_operations_guard.schema.json +578 -0
  166. package/dist/schemas/onchain_operations_machine.schema.json +1 -0
  167. package/dist/schemas/onchain_operations_order.schema.json +4 -3
  168. package/dist/schemas/onchain_operations_payment.schema.json +1 -0
  169. package/dist/schemas/onchain_operations_permission.schema.json +1 -0
  170. package/dist/schemas/onchain_operations_personal.schema.json +37 -0
  171. package/dist/schemas/onchain_operations_progress.schema.json +90 -3
  172. package/dist/schemas/onchain_operations_proof.schema.json +1 -0
  173. package/dist/schemas/onchain_operations_repository.schema.json +1 -0
  174. package/dist/schemas/onchain_operations_reward.schema.json +1 -0
  175. package/dist/schemas/onchain_operations_service.schema.json +4 -3
  176. package/dist/schemas/onchain_operations_treasury.schema.json +1 -0
  177. package/dist/schemas/project_operation.output.json +2243 -1
  178. package/dist/schemas/project_operation.schema.json +683 -1
  179. package/dist/schemas/query_toolkit.output.json +1 -1
  180. package/dist/schemas/query_toolkit.schema.json +37 -0
  181. package/dist/schemas/schema_query.output.json +1 -1
  182. package/dist/schemas/schema_query.schema.json +30 -5
  183. package/dist/schemas/trust_score.output.json +392 -1
  184. package/dist/schemas/trust_score.schema.json +275 -1
  185. package/dist/tools/handlers/onchain.js +73 -8
  186. package/dist/tools/handlers/project.js +46 -0
  187. package/dist/tools/handlers/query.js +117 -2
  188. package/dist/tools/handlers/schema-query.js +41 -0
  189. package/dist/tools/handlers/trust.js +192 -6
  190. package/dist/tools/index.js +52 -9
  191. package/dist/tools/wrap.js +194 -15
  192. package/package.json +2 -2
@@ -72,12 +72,16 @@ export async function resolveTokenByType(tokenType, network) {
72
72
  verified: true,
73
73
  };
74
74
  }
75
+ const memKey = `${cacheNet(network)}::${tokenType}`;
76
+ const memHit = RESOLUTION_CACHE.get(memKey);
77
+ if (memHit)
78
+ return memHit;
75
79
  try {
76
80
  const { TokenInfo } = await import("@wowok/wowok");
77
81
  const tokenInfo = TokenInfo.Instance();
78
82
  const fetched = await tokenInfo.fetch(tokenType, undefined, network);
79
83
  if (fetched) {
80
- return {
84
+ const resolution = {
81
85
  type: fetched.type,
82
86
  symbol: fetched.symbol ?? "",
83
87
  decimals: fetched.decimals ?? 0,
@@ -85,6 +89,8 @@ export async function resolveTokenByType(tokenType, network) {
85
89
  source: "cache",
86
90
  verified: false,
87
91
  };
92
+ RESOLUTION_CACHE.set(memKey, resolution);
93
+ return resolution;
88
94
  }
89
95
  }
90
96
  catch {
@@ -150,13 +156,22 @@ export function isAmountWithSymbol(value) {
150
156
  export async function parseAmount(amount, tokenType, network) {
151
157
  const originalInput = amount;
152
158
  const resolution = await resolveTokenByType(tokenType, network);
159
+ const precisionKnown = resolution !== undefined;
153
160
  const decimals = resolution?.decimals ?? 9;
154
161
  const symbol = resolution?.symbol ?? "";
155
- const source = resolution?.source ?? "registry";
162
+ const source = resolution?.source ?? "onchain";
156
163
  const verified = resolution?.verified ?? false;
157
164
  if (typeof amount === "string") {
158
165
  const match = amount.match(AMOUNT_WITH_SYMBOL);
159
166
  if (match) {
167
+ if (!precisionKnown) {
168
+ throw new Error(`TOKEN PRECISION UNKNOWN for ${tokenType} — REFUSING to convert "${amount}". ` +
169
+ `The token's decimals could not be resolved from the official registry, local cache, ` +
170
+ `or on-chain metadata, and guessing decimals would forge a wrong on-chain value. ` +
171
+ `Retry (the on-chain lookup may have been transient), or pass a pure numeric value ` +
172
+ `in smallest units only if you are certain of the raw u64 amount. ` +
173
+ knownTokenSuggestions(network));
174
+ }
160
175
  const numericPart = parseFloat(match[1]);
161
176
  const symbolPart = match[2];
162
177
  if (symbol && symbolPart.toLowerCase() !== symbol.toLowerCase()) {
@@ -175,6 +190,7 @@ export async function parseAmount(amount, tokenType, network) {
175
190
  converted: true,
176
191
  source,
177
192
  verified,
193
+ precision_known: true,
178
194
  };
179
195
  }
180
196
  }
@@ -186,10 +202,12 @@ export async function parseAmount(amount, tokenType, network) {
186
202
  throw new Error(`Invalid amount: "${amount}". Expected a number, a numeric string (smallest unit), ` +
187
203
  `or a display-format string like "2.5WOW" (matching the token's symbol).`);
188
204
  }
189
- const displayValue = smallestToDisplay(smallestUnit, decimals);
205
+ const displayValue = precisionKnown
206
+ ? smallestToDisplay(smallestUnit, decimals)
207
+ : `${smallestUnit.toString()} raw smallest units (token precision unknown)`;
190
208
  return {
191
209
  smallestUnit,
192
- displayAmount: symbol ? `${displayValue} ${symbol}` : displayValue,
210
+ displayAmount: precisionKnown && symbol ? `${displayValue} ${symbol}` : displayValue,
193
211
  originalInput,
194
212
  tokenType,
195
213
  tokenSymbol: symbol,
@@ -197,6 +215,7 @@ export async function parseAmount(amount, tokenType, network) {
197
215
  converted: false,
198
216
  source,
199
217
  verified,
218
+ precision_known: precisionKnown,
200
219
  };
201
220
  }
202
221
  function displayToSmallestUnit(display, decimals) {
@@ -207,13 +226,27 @@ function displayToSmallestUnit(display, decimals) {
207
226
  return BigInt(combined || "0");
208
227
  }
209
228
  export function smallestToDisplay(value, decimals) {
229
+ const sign = value < 0n ? "-" : "";
230
+ const abs = value < 0n ? -value : value;
210
231
  const divisor = BigInt(10) ** BigInt(decimals);
211
- const whole = value / divisor;
212
- const frac = value % divisor;
232
+ const whole = abs / divisor;
233
+ const frac = abs % divisor;
213
234
  if (frac === 0n)
214
- return whole.toString();
235
+ return `${sign}${whole.toString()}`;
215
236
  const fracStr = frac.toString().padStart(decimals, "0").replace(/0+$/, "");
216
- return `${whole.toString()}.${fracStr}`;
237
+ return `${sign}${whole.toString()}.${fracStr}`;
238
+ }
239
+ export function displayStringToSmallest(display, decimals) {
240
+ const trimmed = display.trim();
241
+ if (!/^\d+(\.\d+)?$/.test(trimmed)) {
242
+ throw new Error(`Invalid display amount: "${display}". Expected a non-negative decimal number like "2.5".`);
243
+ }
244
+ const [whole, frac = ""] = trimmed.split(".");
245
+ if (frac.length > decimals) {
246
+ throw new Error(`Too many decimal places: "${display}" has ${frac.length}, but this token supports at most ${decimals} (decimals: ${decimals}).`);
247
+ }
248
+ const paddedFrac = frac.padEnd(decimals, "0");
249
+ return BigInt(whole + paddedFrac);
217
250
  }
218
251
  export function generateFundConfirmation(fields, ambiguities = []) {
219
252
  const hasAmbiguity = ambiguities.length > 0;
@@ -251,13 +284,16 @@ export function generateFundConfirmation(fields, ambiguities = []) {
251
284
  message: parts.join("\n"),
252
285
  };
253
286
  }
254
- function extractTokenType(data, operationType) {
287
+ function extractTokenType(data, operationType, objectTokenType) {
255
288
  if (data?.object && typeof data.object === "object" && data.object.type_parameter) {
256
289
  return data.object.type_parameter;
257
290
  }
258
291
  if (operationType === "payment" && data?.type_parameter) {
259
292
  return data.type_parameter;
260
293
  }
294
+ if (objectTokenType) {
295
+ return objectTokenType;
296
+ }
261
297
  return GasTokenType;
262
298
  }
263
299
  const MONETARY_FIELDS = {
@@ -281,6 +317,9 @@ const MONETARY_FIELDS = {
281
317
  payment: [
282
318
  { path: "revenue", context: "Payment amount", isArray: true, amountField: "amount.balance" },
283
319
  ],
320
+ allocation: [
321
+ { path: "coin.balance", context: "Allocation funding amount" },
322
+ ],
284
323
  };
285
324
  function getNestedValue(obj, path) {
286
325
  const parts = path.split(".");
@@ -292,17 +331,18 @@ function getNestedValue(obj, path) {
292
331
  }
293
332
  return current;
294
333
  }
295
- export async function processFundOperation(data, operationType, network) {
334
+ export async function processFundOperation(data, operationType, network, options) {
296
335
  const result = {
297
336
  convertedData: data,
298
337
  warnings: [],
338
+ errors: [],
299
339
  confirmation: null,
300
340
  };
301
341
  const fields = MONETARY_FIELDS[operationType];
302
342
  if (!fields) {
303
343
  return result;
304
344
  }
305
- const tokenType = extractTokenType(data, operationType);
345
+ const tokenType = extractTokenType(data, operationType, options?.objectTokenType);
306
346
  const confirmationFields = [];
307
347
  const ambiguities = [];
308
348
  const seenSymbols = new Map();
@@ -364,6 +404,13 @@ async function processSingleField(parentObj, fieldKey, fieldPath, context, token
364
404
  return;
365
405
  try {
366
406
  const parsed = await parseAmount(value, tokenType, network);
407
+ if (!parsed.precision_known) {
408
+ result.errors.push(`FUND INPUT BLOCKED at ${fieldPath}: token precision unavailable for ${tokenType}. ` +
409
+ `The raw value ${JSON.stringify(value)} was NOT converted or confirmed. ` +
410
+ `Retry after the token info resolves (registry → cache → on-chain), ` +
411
+ `or use a known token. ${knownTokenSuggestions(network)}`);
412
+ return;
413
+ }
367
414
  if (parsed.converted) {
368
415
  parentObj[fieldKey] = parsed.smallestUnit.toString();
369
416
  }
@@ -399,7 +446,7 @@ async function processSingleField(parentObj, fieldKey, fieldPath, context, token
399
446
  }
400
447
  }
401
448
  catch (err) {
402
- result.warnings.push(`FUND LAYER ERROR at ${fieldPath}: ${err.message}`);
449
+ result.errors.push(`FUND INPUT BLOCKED at ${fieldPath}: ${err.message}`);
403
450
  }
404
451
  }
405
452
  export function generateSkillsHint(confirmation) {
@@ -418,3 +465,505 @@ export function generateSkillsHint(confirmation) {
418
465
  "dialogue scripts. Otherwise, present the confirmation message to the user " +
419
466
  "and proceed only after explicit consent (env.confirmed=true).");
420
467
  }
468
+ export async function formatChainValue(raw, tokenType, network) {
469
+ let rawStr;
470
+ try {
471
+ rawStr = BigInt(raw).toString();
472
+ }
473
+ catch {
474
+ rawStr = String(raw);
475
+ }
476
+ const resolution = await resolveTokenByType(tokenType, network);
477
+ if (resolution && typeof resolution.decimals === "number") {
478
+ let display = rawStr;
479
+ try {
480
+ display = smallestToDisplay(BigInt(rawStr), resolution.decimals);
481
+ }
482
+ catch {
483
+ }
484
+ const symbol = resolution.symbol || "";
485
+ const text = symbol
486
+ ? `${display} ${symbol} (decimals: ${resolution.decimals}; 1 ${symbol} = 10^${resolution.decimals} raw units; raw: ${rawStr})`
487
+ : `${display} (decimals: ${resolution.decimals}; 1 unit = 10^${resolution.decimals} raw units; raw: ${rawStr})`;
488
+ return {
489
+ raw: rawStr,
490
+ display,
491
+ symbol: symbol || undefined,
492
+ decimals: resolution.decimals,
493
+ token_type: tokenType,
494
+ precision_known: true,
495
+ text,
496
+ };
497
+ }
498
+ return {
499
+ raw: rawStr,
500
+ display: rawStr,
501
+ token_type: tokenType,
502
+ precision_known: false,
503
+ text: `${rawStr} raw smallest units (token precision unavailable for ${tokenType} — ` +
504
+ `cannot convert to unit value. Conversion rule once decimals N is known: ` +
505
+ `unit = raw / 10^N. Re-run the query to retry the on-chain precision lookup.)`,
506
+ };
507
+ }
508
+ export function registryDisplayHint(tokenType, network) {
509
+ if (!tokenType)
510
+ return undefined;
511
+ const entry = findInRegistryByType(tokenType, network);
512
+ if (!entry)
513
+ return undefined;
514
+ return { decimals: entry.decimals, symbol: entry.symbol };
515
+ }
516
+ const RESOLUTION_CACHE = new Map();
517
+ const OBJECT_TYPE_CACHE = new Map();
518
+ function cacheNet(network) {
519
+ return network ?? "default";
520
+ }
521
+ function isCacheableObjectRef(ref) {
522
+ return /^0x[0-9a-fA-F]{20,}$/.test(ref);
523
+ }
524
+ export function clearFundResolutionCaches() {
525
+ RESOLUTION_CACHE.clear();
526
+ OBJECT_TYPE_CACHE.clear();
527
+ }
528
+ export function knownTokenSuggestions(network) {
529
+ const tokens = getRegistryForNetwork(network)
530
+ .map(t => `${t.symbol} (${t.type}, ${t.decimals} decimals)`);
531
+ return tokens.length > 0
532
+ ? `Known tokens: ${tokens.join("; ")}.`
533
+ : "No officially-known tokens on this network.";
534
+ }
535
+ export function formatAmountText(raw, decimals, symbol) {
536
+ let rawStr;
537
+ try {
538
+ rawStr = BigInt(raw).toString();
539
+ }
540
+ catch {
541
+ rawStr = String(raw);
542
+ }
543
+ if (decimals === undefined) {
544
+ return `${rawStr} smallest units (token precision unknown)`;
545
+ }
546
+ let display = rawStr;
547
+ try {
548
+ display = smallestToDisplay(BigInt(rawStr), decimals);
549
+ }
550
+ catch {
551
+ }
552
+ return symbol
553
+ ? `${display} ${symbol} (decimals: ${decimals}; raw: ${rawStr})`
554
+ : `${display} (decimals: ${decimals}; raw: ${rawStr})`;
555
+ }
556
+ export async function convertTokenValue(tokenType, value, network) {
557
+ const resolution = await resolveTokenByType(tokenType, network);
558
+ const decimals = resolution?.decimals;
559
+ const symbol = resolution?.symbol || undefined;
560
+ const base = { token_type: tokenType, symbol, decimals };
561
+ if (value.raw !== undefined) {
562
+ let rawStr;
563
+ try {
564
+ rawStr = BigInt(value.raw).toString();
565
+ }
566
+ catch {
567
+ return {
568
+ ...base,
569
+ precision_known: decimals !== undefined,
570
+ direction: "raw_to_unit",
571
+ input: String(value.raw),
572
+ output: "",
573
+ error: `Invalid raw value: "${String(value.raw)}" — expected a non-negative integer (u64 smallest units).`,
574
+ text: `Cannot convert: invalid raw value "${String(value.raw)}".`,
575
+ };
576
+ }
577
+ if (decimals === undefined) {
578
+ return {
579
+ ...base,
580
+ precision_known: false,
581
+ direction: "raw_to_unit",
582
+ input: rawStr,
583
+ output: rawStr,
584
+ text: `${rawStr} raw smallest units (token precision unavailable for ${tokenType} — ` +
585
+ `cannot convert to unit value. Rule once decimals N is known: unit = raw / 10^N.)`,
586
+ };
587
+ }
588
+ let unit = rawStr;
589
+ try {
590
+ unit = smallestToDisplay(BigInt(rawStr), decimals);
591
+ }
592
+ catch { }
593
+ return {
594
+ ...base,
595
+ precision_known: true,
596
+ direction: "raw_to_unit",
597
+ input: rawStr,
598
+ output: unit,
599
+ text: symbol
600
+ ? `${rawStr} raw = ${unit} ${symbol} (decimals: ${decimals}; 1 ${symbol} = 10^${decimals} raw units)`
601
+ : `${rawStr} raw = ${unit} (decimals: ${decimals}; 1 unit = 10^${decimals} raw units)`,
602
+ };
603
+ }
604
+ const unitStr = String(value.unit ?? "").trim();
605
+ if (decimals === undefined) {
606
+ return {
607
+ ...base,
608
+ precision_known: false,
609
+ direction: "unit_to_raw",
610
+ input: unitStr,
611
+ output: "",
612
+ error: `Token precision unavailable for ${tokenType} — REFUSING to convert "${unitStr}" to raw units. ` +
613
+ `Guessing decimals would forge a wrong on-chain value. Retry after the precision lookup succeeds, ` +
614
+ `or check the token's coin metadata.`,
615
+ text: `Cannot convert "${unitStr}" to raw units: token precision unknown for ${tokenType}.`,
616
+ };
617
+ }
618
+ try {
619
+ const raw = displayStringToSmallest(unitStr, decimals);
620
+ return {
621
+ ...base,
622
+ precision_known: true,
623
+ direction: "unit_to_raw",
624
+ input: unitStr,
625
+ output: raw.toString(),
626
+ text: symbol
627
+ ? `${unitStr} ${symbol} = ${raw.toString()} raw smallest units (decimals: ${decimals}; 1 ${symbol} = 10^${decimals} raw units)`
628
+ : `${unitStr} = ${raw.toString()} raw smallest units (decimals: ${decimals}; 1 unit = 10^${decimals} raw units)`,
629
+ };
630
+ }
631
+ catch (e) {
632
+ const msg = e instanceof Error ? e.message : String(e);
633
+ return {
634
+ ...base,
635
+ precision_known: true,
636
+ direction: "unit_to_raw",
637
+ input: unitStr,
638
+ output: "",
639
+ error: msg,
640
+ text: `Cannot convert "${unitStr}" to raw units: ${msg}`,
641
+ };
642
+ }
643
+ }
644
+ export const TOKEN_GENERIC_OBJECT_TYPES = [
645
+ "Treasury",
646
+ "Allocation",
647
+ "Arbitration",
648
+ "Arb",
649
+ "Payment",
650
+ "Reward",
651
+ "Service",
652
+ ];
653
+ export function extractGenericTokenType(typeRaw) {
654
+ if (!typeRaw || typeof typeRaw !== "string")
655
+ return undefined;
656
+ const lt = typeRaw.indexOf("<");
657
+ if (lt < 0)
658
+ return undefined;
659
+ let depth = 0;
660
+ for (let i = lt; i < typeRaw.length; i++) {
661
+ const ch = typeRaw[i];
662
+ if (ch === "<")
663
+ depth++;
664
+ else if (ch === ">") {
665
+ depth--;
666
+ if (depth === 0) {
667
+ return typeRaw.slice(lt + 1, i).trim() || undefined;
668
+ }
669
+ }
670
+ }
671
+ return undefined;
672
+ }
673
+ export async function resolveObjectTokenType(objectRef, network) {
674
+ if (!objectRef || typeof objectRef !== "string")
675
+ return undefined;
676
+ const cacheable = isCacheableObjectRef(objectRef);
677
+ const memKey = `${cacheNet(network)}::${objectRef}`;
678
+ if (cacheable) {
679
+ const memHit = OBJECT_TYPE_CACHE.get(memKey);
680
+ if (memHit)
681
+ return memHit;
682
+ }
683
+ try {
684
+ const { query_objects } = await import("@wowok/wowok");
685
+ const res = await query_objects({ objects: [objectRef], network });
686
+ const obj = res?.objects?.[0];
687
+ if (!obj)
688
+ return undefined;
689
+ const typeRaw = obj.type_raw ?? obj.content_raw?.type ?? undefined;
690
+ const resolution = {
691
+ tokenType: extractGenericTokenType(typeRaw),
692
+ objectType: obj.type,
693
+ typeRaw,
694
+ };
695
+ if (cacheable)
696
+ OBJECT_TYPE_CACHE.set(memKey, resolution);
697
+ return resolution;
698
+ }
699
+ catch {
700
+ return undefined;
701
+ }
702
+ }
703
+ export async function resolveOperationObjectTokenType(data, operationType, network) {
704
+ if (!data)
705
+ return undefined;
706
+ if (data.object && typeof data.object === "object" && typeof data.object.type_parameter === "string") {
707
+ return data.object.type_parameter;
708
+ }
709
+ if (operationType === "payment" && typeof data.type_parameter === "string") {
710
+ return data.type_parameter;
711
+ }
712
+ if (typeof data.object === "string" && data.object.length > 0) {
713
+ const resolved = await resolveObjectTokenType(data.object, network);
714
+ return resolved?.tokenType;
715
+ }
716
+ return undefined;
717
+ }
718
+ const RECEIVE_TOKEN_FIELDS = {
719
+ treasury: ["receive"],
720
+ allocation: ["received_coins"],
721
+ reward: ["receive"],
722
+ service: ["compensation_fund_receive"],
723
+ arbitration: ["receive"],
724
+ };
725
+ const COIN_PARAM_FIELDS = {
726
+ treasury: ["deposit.coin"],
727
+ allocation: ["coin"],
728
+ reward: ["coin_add"],
729
+ arbitration: ["dispute.fee"],
730
+ service: ["compensation_fund_add", "order_new.buy.total_pay"],
731
+ };
732
+ export async function validateOperationTokenMatch(data, operationType, objectTokenType, network) {
733
+ const result = { errors: [], warnings: [], objectTokenType };
734
+ if (!data || !objectTokenType)
735
+ return result;
736
+ const objectLabel = typeof data.object === "string" ? data.object : "the target object";
737
+ const mismatchMsg = (provided, context) => `TOKEN TYPE MISMATCH (${context}): ${objectLabel} only accepts ${objectTokenType} ` +
738
+ `(its generic token type is fixed and immutable), but ${provided} was provided. ` +
739
+ `Use ${objectTokenType} for this operation, or target a different object.`;
740
+ for (const field of RECEIVE_TOKEN_FIELDS[operationType] ?? []) {
741
+ const v = data[field];
742
+ if (v && typeof v === "object" && typeof v.token_type === "string" && v.token_type !== objectTokenType) {
743
+ result.errors.push(mismatchMsg(v.token_type, `field '${field}.token_type'`));
744
+ }
745
+ }
746
+ for (const path of COIN_PARAM_FIELDS[operationType] ?? []) {
747
+ const coinParam = getNestedValue(data, path);
748
+ if (coinParam && typeof coinParam === "object" && typeof coinParam.coin === "string") {
749
+ const coinRef = coinParam.coin;
750
+ const resolved = await resolveObjectTokenType(coinRef, network);
751
+ if (resolved?.tokenType) {
752
+ if (resolved.tokenType !== objectTokenType) {
753
+ result.errors.push(mismatchMsg(resolved.tokenType, `coin '${coinRef}' at '${path}'`));
754
+ }
755
+ }
756
+ else if (resolved === undefined) {
757
+ result.warnings.push(`Could not resolve coin object '${coinRef}' (${path}) to verify its token type ` +
758
+ `matches ${objectTokenType}. The on-chain type check will reject a mismatch at execution.`);
759
+ }
760
+ }
761
+ }
762
+ return result;
763
+ }
764
+ const OBJECT_MONEY_FIELDS = {
765
+ Treasury: ["balance", "inflow", "outflow"],
766
+ Allocation: ["balance"],
767
+ Arbitration: ["fee", "balance"],
768
+ Reward: ["balance"],
769
+ Service: ["compensation_fund"],
770
+ Payment: ["amount"],
771
+ Arb: ["fee"],
772
+ };
773
+ export async function annotateObjectMonetaryFields(obj, network) {
774
+ if (!obj || typeof obj !== "object" || typeof obj.type !== "string")
775
+ return;
776
+ let tokenType = extractGenericTokenType(obj.type_raw);
777
+ const displays = {};
778
+ const annotate = async (path, raw, tt) => {
779
+ if (raw === null || raw === undefined)
780
+ return;
781
+ if (typeof raw !== "string" && typeof raw !== "number" && typeof raw !== "bigint")
782
+ return;
783
+ displays[path] = tt
784
+ ? await formatChainValue(raw, tt, network)
785
+ : {
786
+ raw: String(raw),
787
+ display: String(raw),
788
+ token_type: "",
789
+ precision_known: false,
790
+ text: `${String(raw)} raw smallest units (token type could not be determined for this field — ` +
791
+ `no conversion applied. Showing the true raw value; re-run the query to retry resolution.)`,
792
+ };
793
+ };
794
+ if (!tokenType && (obj.type === "Order" || obj.type === "Discount") && typeof obj.service === "string") {
795
+ try {
796
+ const svc = await resolveObjectTokenType(obj.service, network);
797
+ tokenType = svc?.tokenType;
798
+ }
799
+ catch {
800
+ }
801
+ }
802
+ for (const field of OBJECT_MONEY_FIELDS[obj.type] ?? []) {
803
+ await annotate(field, obj[field], tokenType);
804
+ }
805
+ switch (obj.type) {
806
+ case "Service":
807
+ if (Array.isArray(obj.sales)) {
808
+ for (let i = 0; i < obj.sales.length; i++) {
809
+ await annotate(`sales[${i}].price`, obj.sales[i]?.price, tokenType);
810
+ }
811
+ }
812
+ break;
813
+ case "Order":
814
+ await annotate("amount", obj.amount, tokenType);
815
+ if (Array.isArray(obj.items)) {
816
+ for (let i = 0; i < obj.items.length; i++) {
817
+ await annotate(`items[${i}].price`, obj.items[i]?.price, tokenType);
818
+ }
819
+ }
820
+ break;
821
+ case "Payment":
822
+ if (Array.isArray(obj.record)) {
823
+ for (let i = 0; i < obj.record.length; i++) {
824
+ await annotate(`record[${i}].amount`, obj.record[i]?.amount, tokenType);
825
+ }
826
+ }
827
+ break;
828
+ case "Reward":
829
+ if (Array.isArray(obj.guards)) {
830
+ for (let i = 0; i < obj.guards.length; i++) {
831
+ const amount = obj.guards[i]?.amount;
832
+ if (amount && typeof amount === "object" && amount.type === 1) {
833
+ await annotate(`guards[${i}].amount.value`, amount.value, tokenType);
834
+ }
835
+ }
836
+ }
837
+ break;
838
+ case "Arb":
839
+ await annotate("indemnity.amount", obj.indemnity?.amount, tokenType);
840
+ break;
841
+ case "Discount":
842
+ await annotate("benchmark", obj.benchmark, tokenType);
843
+ if (obj.discount_type === 1) {
844
+ await annotate("off", obj.off, tokenType);
845
+ }
846
+ break;
847
+ }
848
+ if (Object.keys(displays).length > 0) {
849
+ obj._money_display = displays;
850
+ }
851
+ }
852
+ const TABLE_ITEM_MONEY_FIELDS = {
853
+ TableItem_TreasuryHistory: ["amount"],
854
+ TableItem_RewardRecord: ["total"],
855
+ };
856
+ export async function resolveParentObjectTokenType(parentRef, network) {
857
+ const res = await resolveObjectTokenType(parentRef, network);
858
+ if (!res)
859
+ return undefined;
860
+ if (res.objectType && TOKEN_GENERIC_OBJECT_TYPES.includes(res.objectType)) {
861
+ return res.tokenType;
862
+ }
863
+ return undefined;
864
+ }
865
+ export async function annotateTableItemMonetaryFields(item, parentTokenType, network) {
866
+ if (!item || typeof item !== "object" || typeof item.type !== "string")
867
+ return;
868
+ const displays = {};
869
+ const annotate = async (path, raw) => {
870
+ if (raw === null || raw === undefined)
871
+ return;
872
+ if (typeof raw !== "string" && typeof raw !== "number" && typeof raw !== "bigint")
873
+ return;
874
+ displays[path] = parentTokenType
875
+ ? await formatChainValue(raw, parentTokenType, network)
876
+ : {
877
+ raw: String(raw),
878
+ display: String(raw),
879
+ token_type: "",
880
+ precision_known: false,
881
+ text: `${String(raw)} raw smallest units (parent object token type could not ` +
882
+ `be resolved — no conversion applied)`,
883
+ };
884
+ };
885
+ for (const field of TABLE_ITEM_MONEY_FIELDS[item.type] ?? []) {
886
+ await annotate(field, item[field]);
887
+ }
888
+ if (item.type === "TableItem_RewardRecord" && Array.isArray(item.record)) {
889
+ for (let i = 0; i < item.record.length; i++) {
890
+ await annotate(`record[${i}].amount`, item.record[i]?.amount);
891
+ }
892
+ }
893
+ if (Object.keys(displays).length > 0) {
894
+ item._money_display = displays;
895
+ }
896
+ }
897
+ export async function annotateEventMonetaryFields(event, network) {
898
+ if (!event || typeof event !== "object")
899
+ return;
900
+ if (event.type !== "NewOrderEvent")
901
+ return;
902
+ const raw = event.amount;
903
+ if (raw === null || raw === undefined)
904
+ return;
905
+ if (typeof raw !== "string" && typeof raw !== "number" && typeof raw !== "bigint")
906
+ return;
907
+ let tokenType;
908
+ if (typeof event.service === "string" && event.service) {
909
+ try {
910
+ tokenType = (await resolveObjectTokenType(event.service, network))?.tokenType;
911
+ }
912
+ catch {
913
+ }
914
+ }
915
+ event._money_display = {
916
+ amount: tokenType
917
+ ? await formatChainValue(raw, tokenType, network)
918
+ : {
919
+ raw: String(raw),
920
+ display: String(raw),
921
+ token_type: "",
922
+ precision_known: false,
923
+ text: `${String(raw)} raw smallest units (order's Service token type could not be ` +
924
+ `resolved — showing the true raw value; re-run the query to retry.)`,
925
+ },
926
+ };
927
+ }
928
+ export async function annotateEventsMonetaryFields(events, network) {
929
+ if (!Array.isArray(events))
930
+ return;
931
+ for (const ev of events) {
932
+ try {
933
+ await annotateEventMonetaryFields(ev, network);
934
+ }
935
+ catch {
936
+ }
937
+ }
938
+ }
939
+ export async function annotateBalanceChanges(changes, network) {
940
+ if (!Array.isArray(changes))
941
+ return;
942
+ for (const change of changes) {
943
+ try {
944
+ const coinType = change?.coin_type;
945
+ const raw = change?.amount;
946
+ if (typeof coinType !== "string" || !coinType)
947
+ continue;
948
+ if (typeof raw !== "string" && typeof raw !== "number" && typeof raw !== "bigint")
949
+ continue;
950
+ change._money_display = {
951
+ amount: await formatChainValue(raw, coinType, network),
952
+ };
953
+ }
954
+ catch {
955
+ }
956
+ }
957
+ }
958
+ export async function prepareFundOperation(data, operationType, network) {
959
+ const objectTokenType = await resolveOperationObjectTokenType(data, operationType, network);
960
+ const match = await validateOperationTokenMatch(data, operationType, objectTokenType, network);
961
+ const processed = await processFundOperation(data, operationType, network, { objectTokenType });
962
+ return {
963
+ ...processed,
964
+ warnings: [...match.warnings, ...processed.warnings],
965
+ matchErrors: match.errors,
966
+ blockingErrors: [...match.errors, ...processed.errors],
967
+ objectTokenType,
968
+ };
969
+ }
@@ -34,5 +34,15 @@ export declare function validateTemplateParams(templateId: string, params: Recor
34
34
  valid: boolean;
35
35
  missing: string[];
36
36
  };
37
+ export type FillGuardTemplateResult = {
38
+ ok: true;
39
+ table: unknown;
40
+ root: unknown;
41
+ } | {
42
+ ok: false;
43
+ error: string;
44
+ missing?: string[];
45
+ };
46
+ export declare function fillGuardTemplate(templateId: string, params: Record<string, unknown>): FillGuardTemplateResult;
37
47
  export declare const GUARD_TEMPLATES_VERSION = "1.0.0";
38
48
  export declare const GUARD_TEMPLATES_COUNT: number;