@stelis/say-ur-intent 0.0.0 → 0.0.2

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 (234) hide show
  1. package/README.md +4 -39
  2. package/dist/adapters/adapterLifecycleValidators.js +7 -0
  3. package/dist/adapters/adapterPromptSurfaces.js +71 -0
  4. package/dist/adapters/deepbook/deepbookHumanReviewProducer.js +175 -0
  5. package/dist/adapters/deepbook/deepbookQuotePolicy.js +112 -0
  6. package/dist/adapters/deepbook/deepbookReviewEvidence.js +507 -0
  7. package/dist/adapters/deepbook/deepbookReviewLifecycle.js +85 -0
  8. package/dist/adapters/deepbook/deepbookSwapIntent.js +79 -0
  9. package/dist/adapters/deepbook/deepbookTransactionMaterialProducer.js +269 -0
  10. package/dist/adapters/flowx/flowxSwapHumanReviewProducer.js +176 -0
  11. package/dist/adapters/flowx/flowxSwapIntent.js +79 -0
  12. package/dist/adapters/flowx/flowxSwapQuotePolicy.js +104 -0
  13. package/dist/adapters/flowx/flowxSwapReviewEvidence.js +468 -0
  14. package/dist/adapters/flowx/flowxSwapReviewLifecycle.js +85 -0
  15. package/dist/adapters/flowx/flowxSwapTransactionMaterialProducer.js +362 -0
  16. package/dist/adapters/intentPlanFactories.js +59 -0
  17. package/dist/adapters/reviewAdapters.js +81 -0
  18. package/dist/core/action/adapterLifecycleValidation.js +12 -0
  19. package/dist/core/action/forbiddenFields.js +43 -0
  20. package/dist/core/action/humanReadableReviewEvidence.js +203 -0
  21. package/dist/core/action/humanReadableReviewProjectionVerifier.js +29 -0
  22. package/dist/core/action/ptbVisualizationProducer.js +66 -0
  23. package/dist/core/action/reviewCheckResults.js +6 -0
  24. package/dist/core/action/reviewStateValidation.js +11 -0
  25. package/dist/core/action/reviewTimeSimulationEvidence.js +471 -0
  26. package/dist/core/action/schemas.js +529 -0
  27. package/dist/core/action/signableAdapterContract.js +993 -0
  28. package/dist/core/action/swapHumanReadableReviewProjection.js +124 -0
  29. package/dist/core/action/swapQuotePolicyEvidence.js +278 -0
  30. package/dist/core/action/transactionObjectOwnershipEvidence.js +247 -0
  31. package/dist/core/action/transactionObjectOwnershipProducer.js +329 -0
  32. package/dist/core/action/types.js +35 -0
  33. package/dist/core/action/walletReviewContractAssembler.js +282 -0
  34. package/dist/core/activity/activityStore.js +15 -0
  35. package/dist/core/activity/localDataService.js +258 -0
  36. package/dist/core/activity/localDataTypes.js +11 -0
  37. package/dist/core/activity/localDataValidation.js +396 -0
  38. package/dist/core/activity/schemaVersion.js +1 -0
  39. package/dist/core/activity/sqliteActivityStore.js +820 -0
  40. package/dist/core/activity/sqliteActivityStoreRows.js +430 -0
  41. package/dist/core/activity/sqliteActivityStoreSchema.js +258 -0
  42. package/dist/core/activity/sqliteActivityStoreTypes.js +5 -0
  43. package/dist/core/activity/suiFunctionTarget.js +43 -0
  44. package/dist/core/activity/transactionActivityAccountEffects.js +189 -0
  45. package/dist/core/activity/transactionActivityAnalysis.js +295 -0
  46. package/dist/core/activity/transactionActivityClassifier.js +306 -0
  47. package/dist/core/activity/transactionActivityDetails.js +229 -0
  48. package/dist/core/activity/transactionActivityProtocolRules.js +218 -0
  49. package/dist/core/activity/transactionActivityScanPolicy.js +170 -0
  50. package/dist/core/activity/transactionActivityService.js +379 -0
  51. package/dist/core/activity/transactionActivityTypes.js +18 -0
  52. package/dist/core/eventlog/sink.js +35 -0
  53. package/dist/core/evidence/settlementFamilies.js +87 -0
  54. package/dist/core/evidence/userAnswerUse.js +1 -0
  55. package/dist/core/numeric/rawU64.js +63 -0
  56. package/dist/core/preferences/preferencesStore.js +26 -0
  57. package/dist/core/preferences/sqlitePreferencesRepository.js +136 -0
  58. package/dist/core/proposal/externalProposalReview.js +347 -0
  59. package/dist/core/proposal/schemas.js +208 -0
  60. package/dist/core/proposal/types.js +35 -0
  61. package/dist/core/read/amounts.js +14 -0
  62. package/dist/core/read/coinMetadata.js +60 -0
  63. package/dist/core/read/deepbookRawQuoteClient.js +86 -0
  64. package/dist/core/read/deepbookReadHelpers.js +265 -0
  65. package/dist/core/read/deepbookRegistry.js +133 -0
  66. package/dist/core/read/flowxQuoteClient.js +117 -0
  67. package/dist/core/read/flowxReadHelpers.js +145 -0
  68. package/dist/core/read/flowxRegistry.js +174 -0
  69. package/dist/core/read/intentEvidenceResponseFormatting.js +228 -0
  70. package/dist/core/read/readResponseGuidance.js +451 -0
  71. package/dist/core/read/readService.js +1164 -0
  72. package/dist/core/read/readServiceTypes.js +59 -0
  73. package/dist/core/read/settlementParityFormatting.js +82 -0
  74. package/dist/core/read/walletReadHelpers.js +99 -0
  75. package/dist/core/review/reviewChecks.js +54 -0
  76. package/dist/core/review/reviewComputation.js +38 -0
  77. package/dist/core/review/reviewComputationResult.js +87 -0
  78. package/dist/core/session/localSession.js +31 -0
  79. package/dist/core/session/privateReviewArtifacts.js +73 -0
  80. package/dist/core/session/sessionErrors.js +9 -0
  81. package/dist/core/session/sessionStore.js +821 -0
  82. package/dist/core/session/settingsSession.js +1 -0
  83. package/dist/core/session/settingsSessions.js +43 -0
  84. package/dist/core/session/status.js +86 -0
  85. package/dist/core/session/transactionMaterialStore.js +205 -0
  86. package/dist/core/session/wait.js +102 -0
  87. package/dist/core/session/walletIdentity.js +103 -0
  88. package/dist/core/session/walletIdentitySessions.js +189 -0
  89. package/dist/core/suiAddress.js +18 -0
  90. package/dist/core/suiEndpoint.js +72 -0
  91. package/dist/mcp/activeAccountResponse.js +24 -0
  92. package/dist/mcp/prompts.js +146 -0
  93. package/dist/mcp/registerTool.js +19 -0
  94. package/dist/mcp/resources.js +72 -0
  95. package/dist/mcp/responseGuidance.js +381 -0
  96. package/dist/mcp/result.js +17 -0
  97. package/dist/mcp/schemas.js +8 -0
  98. package/dist/mcp/server.js +30 -0
  99. package/dist/mcp/serverInfo.js +123 -0
  100. package/dist/mcp/toolErrors.js +105 -0
  101. package/dist/mcp/toolNames.js +50 -0
  102. package/dist/mcp/tools/account/index.js +44 -0
  103. package/dist/mcp/tools/action/prepareSuiActionReview.js +120 -0
  104. package/dist/mcp/tools/read/commonSchemas.js +43 -0
  105. package/dist/mcp/tools/read/deepbookReadTools.js +453 -0
  106. package/dist/mcp/tools/read/flowxReadTools.js +135 -0
  107. package/dist/mcp/tools/read/index.js +16 -0
  108. package/dist/mcp/tools/read/readToolHelpers.js +68 -0
  109. package/dist/mcp/tools/read/reviewActivityTools.js +176 -0
  110. package/dist/mcp/tools/read/serverStatusTools.js +103 -0
  111. package/dist/mcp/tools/read/transactionActivityOutput.js +300 -0
  112. package/dist/mcp/tools/read/transactionActivityTools.js +544 -0
  113. package/dist/mcp/tools/read/walletReadTools.js +733 -0
  114. package/dist/mcp/tools/session/executionResultTools.js +92 -0
  115. package/dist/mcp/tools/session/index.js +8 -0
  116. package/dist/mcp/tools/session/shared.js +79 -0
  117. package/dist/mcp/tools/session/statusTools.js +134 -0
  118. package/dist/mcp/tools/session/walletIdentityTools.js +119 -0
  119. package/dist/mcp/tools/settings/index.js +64 -0
  120. package/dist/review-app/analysis.css +1 -0
  121. package/dist/review-app/analysis.js +1 -0
  122. package/dist/review-app/arc-BjIacwQm.js +1 -0
  123. package/dist/review-app/architecture-U656AL7Q-aSB9x1OK.js +1 -0
  124. package/dist/review-app/architectureDiagram-VXUJARFQ-C5W6re2I.js +36 -0
  125. package/dist/review-app/array-BmXUUrU6.js +1 -0
  126. package/dist/review-app/blockDiagram-VD42YOAC-20MLNcUm.js +122 -0
  127. package/dist/review-app/c4Diagram-YG6GDRKO-BZXRrcck.js +10 -0
  128. package/dist/review-app/channel-lk2p_CUu.js +1 -0
  129. package/dist/review-app/chunk-4BX2VUAB-BPITOdjX.js +1 -0
  130. package/dist/review-app/chunk-55IACEB6-Dz-pyw5k.js +1 -0
  131. package/dist/review-app/chunk-76Q3JFCE-cK_X1P_l.js +1 -0
  132. package/dist/review-app/chunk-ABZYJK2D-Dt4W53JI.js +81 -0
  133. package/dist/review-app/chunk-ATLVNIR6-fZHLXURb.js +1 -0
  134. package/dist/review-app/chunk-B4BG7PRW-BbgcjusC.js +165 -0
  135. package/dist/review-app/chunk-BJD4TVEz.js +1 -0
  136. package/dist/review-app/chunk-CVBHYZKI-CViawAKX.js +1 -0
  137. package/dist/review-app/chunk-DI55MBZ5-C5aoul-d.js +220 -0
  138. package/dist/review-app/chunk-FMBD7UC4-Chxmw62A.js +15 -0
  139. package/dist/review-app/chunk-FPAJGGOC-DDHjQ09H.js +80 -0
  140. package/dist/review-app/chunk-FWNWRKHM-CVVQUptk.js +1 -0
  141. package/dist/review-app/chunk-HN2XXSSU-yzNpjaSZ.js +1 -0
  142. package/dist/review-app/chunk-JA3XYJ7Z-C5ZJdU01.js +70 -0
  143. package/dist/review-app/chunk-JZLCHNYA-BBST4Cnk.js +54 -0
  144. package/dist/review-app/chunk-LBM3YZW2-CdwAPuHr.js +1 -0
  145. package/dist/review-app/chunk-LHMN2FUI-BtB5uDcp.js +1 -0
  146. package/dist/review-app/chunk-O7ZBX7Z2-pxdK4Sa3.js +1 -0
  147. package/dist/review-app/chunk-QN33PNHL-CbVv3uGK.js +1 -0
  148. package/dist/review-app/chunk-QXUST7PY-DKM2-t2c.js +7 -0
  149. package/dist/review-app/chunk-QZHKN3VN-C5ni2pN_.js +1 -0
  150. package/dist/review-app/chunk-S3R3BYOJ-BWvOhDs0.js +2 -0
  151. package/dist/review-app/chunk-S6J4BHB3-D9Fk0YeD.js +1 -0
  152. package/dist/review-app/chunk-T53DSG4Q-C1qEyzyV.js +1 -0
  153. package/dist/review-app/chunk-TZMSLE5B-B--7eU69.js +1 -0
  154. package/dist/review-app/classDiagram-2ON5EDUG-DlL1m2bp.js +1 -0
  155. package/dist/review-app/classDiagram-v2-WZHVMYZB-FXRskT1j.js +1 -0
  156. package/dist/review-app/clone-BZZb7gpZ.js +1 -0
  157. package/dist/review-app/cose-bilkent-S5V4N54A-CRIb8XEO.js +1 -0
  158. package/dist/review-app/cytoscape.esm-C7jYqDP5.js +321 -0
  159. package/dist/review-app/dagre-6UL2VRFP-FNCAXbdE.js +4 -0
  160. package/dist/review-app/dagre-Be46QtUd.js +1 -0
  161. package/dist/review-app/defaultLocale-BaWNtAUL.js +1 -0
  162. package/dist/review-app/diagram-PSM6KHXK-ylLWjiNM.js +24 -0
  163. package/dist/review-app/diagram-QEK2KX5R-BCDcESxs.js +43 -0
  164. package/dist/review-app/diagram-S2PKOQOG-Vdrc-vrO.js +24 -0
  165. package/dist/review-app/dist-WPc74x_f.js +1 -0
  166. package/dist/review-app/erDiagram-Q2GNP2WA-E5ZsUbDF.js +60 -0
  167. package/dist/review-app/flatten-DHf9IeNI.js +1 -0
  168. package/dist/review-app/flowDiagram-NV44I4VS-DBSQuj6x.js +162 -0
  169. package/dist/review-app/ganttDiagram-LVOFAZNH-CKUOsqwl.js +267 -0
  170. package/dist/review-app/gitGraph-F6HP7TQM-DsAD6qK1.js +1 -0
  171. package/dist/review-app/gitGraphDiagram-NY62KEGX-BCeIMWdl.js +65 -0
  172. package/dist/review-app/graphlib-CiX5CXxR.js +1 -0
  173. package/dist/review-app/http-DMvwuuFk.js +1 -0
  174. package/dist/review-app/identity-DY8PXc6t.js +1 -0
  175. package/dist/review-app/info-NVLQJR56-Dlx1nZic.js +1 -0
  176. package/dist/review-app/infoDiagram-F6ZHWCRC-CAuANIrz.js +2 -0
  177. package/dist/review-app/init-BvqephKz.js +1 -0
  178. package/dist/review-app/journeyDiagram-XKPGCS4Q-C-Z9phnx.js +139 -0
  179. package/dist/review-app/kanban-definition-3W4ZIXB7-DufgZABq.js +89 -0
  180. package/dist/review-app/katex-B-Z-NXXN.js +257 -0
  181. package/dist/review-app/line-DiIv3Jgw.js +1 -0
  182. package/dist/review-app/linear-Cv-UPvo1.js +1 -0
  183. package/dist/review-app/math-kmyYrkHL.js +1 -0
  184. package/dist/review-app/mermaid-parser.core-DkwUYTPl.js +4 -0
  185. package/dist/review-app/mindmap-definition-VGOIOE7T-TM_CqdmV.js +68 -0
  186. package/dist/review-app/ordinal-BliTlkoG.js +1 -0
  187. package/dist/review-app/packet-BFZMPI3H-DqbnU92v.js +1 -0
  188. package/dist/review-app/path-AEo9W6mQ.js +1 -0
  189. package/dist/review-app/pie-7BOR55EZ-LJzaLkgr.js +1 -0
  190. package/dist/review-app/pieDiagram-ADFJNKIX-BAs8OfRS.js +30 -0
  191. package/dist/review-app/quadrantDiagram-AYHSOK5B-CyUDZP5S.js +7 -0
  192. package/dist/review-app/radar-NHE76QYJ-DBpHc8_Y.js +1 -0
  193. package/dist/review-app/reduce-B-HuPpdd.js +1 -0
  194. package/dist/review-app/requirementDiagram-UZGBJVZJ-BEHix78P.js +64 -0
  195. package/dist/review-app/review.css +1 -0
  196. package/dist/review-app/review.js +43 -0
  197. package/dist/review-app/sankeyDiagram-TZEHDZUN-B2bKbmsm.js +10 -0
  198. package/dist/review-app/sequenceDiagram-WL72ISMW-DVLOORFJ.js +145 -0
  199. package/dist/review-app/settings.css +1 -0
  200. package/dist/review-app/settings.js +1 -0
  201. package/dist/review-app/src-Buml7cM5.js +1 -0
  202. package/dist/review-app/stateDiagram-FKZM4ZOC-sFGGp2kV.js +1 -0
  203. package/dist/review-app/stateDiagram-v2-4FDKWEC3-BHfCF4dX.js +1 -0
  204. package/dist/review-app/timeline-definition-IT6M3QCI-BESnBijC.js +61 -0
  205. package/dist/review-app/treemap-KMMF4GRG-wnVLBDeQ.js +1 -0
  206. package/dist/review-app/walletStatus-CcojOdGy.js +7 -0
  207. package/dist/review-app/xychartDiagram-PRI3JC2R-BGWVfCx4.js +7 -0
  208. package/dist/review-server/assets.js +48 -0
  209. package/dist/review-server/html.js +66 -0
  210. package/dist/review-server/http.js +47 -0
  211. package/dist/review-server/middleware/hostOrigin.js +48 -0
  212. package/dist/review-server/middleware/reviewToken.js +7 -0
  213. package/dist/review-server/reviewServerPolicy.js +10 -0
  214. package/dist/review-server/server.js +568 -0
  215. package/dist/review-server/settingsApi.js +182 -0
  216. package/dist/review-server/walletIdentityResponse.js +13 -0
  217. package/dist/runtime/config.js +103 -0
  218. package/dist/runtime/localSettingsService.js +198 -0
  219. package/dist/runtime/logger.js +50 -0
  220. package/dist/runtime/reviewServerAcquire.js +128 -0
  221. package/dist/runtime/smokeMainnetRead.js +529 -0
  222. package/dist/runtime/smokeMainnetReadAssertions.js +308 -0
  223. package/dist/runtime/start.js +295 -0
  224. package/dist/runtime/suiEndpoint.js +97 -0
  225. package/dist/runtime/suiTransactionGraphqlMapping.js +200 -0
  226. package/dist/runtime/suiTransactionGraphqlQueries.js +231 -0
  227. package/dist/runtime/suiTransactionGraphqlSource.js +148 -0
  228. package/docs/AGENT_BEHAVIOR.md +1 -1
  229. package/docs/AGENT_DEVELOPMENT_POLICY.md +20 -0
  230. package/docs/FRONTEND_POLICY.md +4 -3
  231. package/docs/MCP_SETUP.md +59 -7
  232. package/docs/MCP_TOOLS.md +1 -1
  233. package/docs/SDK_API.md +5 -1
  234. package/package.json +3 -2
@@ -0,0 +1,529 @@
1
+ import { mainnetCoins } from "@mysten/deepbook-v3";
2
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { randomInt } from "node:crypto";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
7
+ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
8
+ import { validateSupportedAdapterLifecycle } from "../adapters/adapterLifecycleValidators.js";
9
+ import { SqliteActivityStore } from "../core/activity/sqliteActivityStore.js";
10
+ import { TransactionActivityService } from "../core/activity/transactionActivityService.js";
11
+ import { createSuiReadService } from "../core/read/readService.js";
12
+ import { InMemorySessionStore } from "../core/session/sessionStore.js";
13
+ import { createMcpServer } from "../mcp/server.js";
14
+ import { TOOL_NAMES } from "../mcp/toolNames.js";
15
+ import { createReviewHttpServer } from "../review-server/server.js";
16
+ import { InMemoryLocalTransactionMaterialStore } from "../core/session/transactionMaterialStore.js";
17
+ import { buildSupportedReviewAdapters } from "../adapters/reviewAdapters.js";
18
+ import { createDeepbookSwapTransactionMaterialDigestProducer, createDeepbookSwapTransactionMaterialProducer } from "../adapters/deepbook/deepbookTransactionMaterialProducer.js";
19
+ import { createDeepbookSwapHumanReadableReviewProducer } from "../adapters/deepbook/deepbookHumanReviewProducer.js";
20
+ import { createTransactionObjectOwnershipProducer } from "../core/action/transactionObjectOwnershipProducer.js";
21
+ import { createReviewTimeSimulationProducer } from "../core/action/reviewTimeSimulationEvidence.js";
22
+ import { producePtbVisualizationArtifact } from "../core/action/ptbVisualizationProducer.js";
23
+ import { DEFAULT_SUI_GRAPHQL_URL, DEFAULT_SUI_GRPC_URL, composeRuntimeConfig, loadBootConfig } from "./config.js";
24
+ import { RuntimeLocalSettingsService } from "./localSettingsService.js";
25
+ import { createStderrLogger } from "./logger.js";
26
+ import { SmokeResponseShapeError, assertSmokeOkStatus, summarizeActivitySmokePayload } from "./smokeMainnetReadAssertions.js";
27
+ import { SuiEndpointError, verifyMainnetGraphqlEndpoint, verifyMainnetGrpcEndpoint } from "./suiEndpoint.js";
28
+ import { GraphqlSuiTransactionActivitySource } from "./suiTransactionGraphqlSource.js";
29
+ const startedAt = new Date();
30
+ const smokeFunctionTarget = process.env.SMOKE_FUNCTION_TARGET;
31
+ const plannedTools = [
32
+ TOOL_NAMES.sessionCreateWalletIdentity,
33
+ TOOL_NAMES.readSummarizeWalletAssets,
34
+ TOOL_NAMES.readInspectDeepbookOrderbook,
35
+ TOOL_NAMES.readQuoteDeepbookAction,
36
+ TOOL_NAMES.readScanSuiAccountActivity,
37
+ TOOL_NAMES.readSummarizeSuiActivityScan,
38
+ ...(smokeFunctionTarget
39
+ ? [
40
+ TOOL_NAMES.readScanSuiFunctionActivity,
41
+ TOOL_NAMES.readSummarizeSuiFunctionActivityScan
42
+ ]
43
+ : [])
44
+ ];
45
+ const attemptedTools = [];
46
+ const completedTools = [];
47
+ const activitySmoke = {};
48
+ const functionActivitySmoke = smokeFunctionTarget
49
+ ? {
50
+ tools: [
51
+ TOOL_NAMES.readScanSuiFunctionActivity,
52
+ TOOL_NAMES.readSummarizeSuiFunctionActivityScan
53
+ ]
54
+ }
55
+ : {
56
+ status: "not_run",
57
+ tools: [
58
+ TOOL_NAMES.readScanSuiFunctionActivity,
59
+ TOOL_NAMES.readSummarizeSuiFunctionActivityScan
60
+ ],
61
+ notRunReason: "missing_env"
62
+ };
63
+ const ACTIVITY_SMOKE_LIMIT = 5;
64
+ class SmokeMainnetError extends Error {
65
+ category;
66
+ constructor(category, message) {
67
+ super(message);
68
+ this.category = category;
69
+ }
70
+ }
71
+ async function main() {
72
+ const logger = createStderrLogger("smoke-mainnet");
73
+ const bootConfig = loadSmokeBootConfig();
74
+ const smokeAddress = requiredEnv("SMOKE_SUI_ADDRESS");
75
+ const poolKey = requiredEnv("SMOKE_DEEPBOOK_POOL_KEY");
76
+ const quoteAmount = requiredEnv("SMOKE_QUOTE_AMOUNT");
77
+ const inspectDigest = process.env.SMOKE_INSPECT_DIGEST;
78
+ const inspectRandomLatest = truthyEnv("SMOKE_INSPECT_RANDOM_LATEST");
79
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
80
+ const client = new Client({ name: "say-ur-intent-smoke", version: "0.0.0" });
81
+ let smokeDbDir;
82
+ let activityStore;
83
+ let server;
84
+ let reviewServer;
85
+ try {
86
+ smokeDbDir = mkdtempSync(join(tmpdir(), "say-ur-intent-smoke-db-"));
87
+ activityStore = new SqliteActivityStore({
88
+ databasePath: join(smokeDbDir, "say-ur-intent.sqlite"),
89
+ validateAdapterLifecycle: validateSupportedAdapterLifecycle
90
+ });
91
+ const preferencesRepository = activityStore.createPreferencesRepository();
92
+ await preferencesRepository.ensureDefaultLocalSettings({
93
+ suiGrpcUrl: DEFAULT_SUI_GRPC_URL,
94
+ suiGraphqlUrl: DEFAULT_SUI_GRAPHQL_URL
95
+ });
96
+ const storedSuiGrpcUrl = await preferencesRepository.getSuiGrpcUrl();
97
+ const storedSuiGraphqlUrl = await preferencesRepository.getSuiGraphqlUrl();
98
+ const config = composeRuntimeConfig({
99
+ bootConfig,
100
+ env: process.env,
101
+ storedSuiGrpcUrl: storedSuiGrpcUrl?.value,
102
+ storedSuiGraphqlUrl: storedSuiGraphqlUrl?.value,
103
+ defaultSuiGrpcUrl: DEFAULT_SUI_GRPC_URL,
104
+ defaultSuiGraphqlUrl: DEFAULT_SUI_GRAPHQL_URL
105
+ });
106
+ const { client: suiClient, chainIdentifier } = await verifyMainnetGrpcEndpoint({
107
+ url: config.grpcUrl,
108
+ expectedChainIdentifier: config.expectedChainIdentifier
109
+ });
110
+ const localSettings = new RuntimeLocalSettingsService({
111
+ preferencesRepository,
112
+ env: process.env,
113
+ defaultSuiGrpcUrl: DEFAULT_SUI_GRPC_URL,
114
+ defaultSuiGraphqlUrl: DEFAULT_SUI_GRAPHQL_URL,
115
+ bootSuiGrpcUrl: config.suiGrpcUrl,
116
+ bootSuiGraphqlUrl: config.suiGraphqlUrl
117
+ });
118
+ const readService = createSuiReadService({
119
+ client: suiClient,
120
+ network: config.network,
121
+ chainIdentifier,
122
+ coinMetadataCache: activityStore.createCoinMetadataCache()
123
+ });
124
+ const transactionMaterialStore = new InMemoryLocalTransactionMaterialStore();
125
+ const sessions = new InMemorySessionStore({
126
+ activityStore,
127
+ logger,
128
+ validateAdapterLifecycle: validateSupportedAdapterLifecycle
129
+ });
130
+ reviewServer = await createReviewHttpServer({
131
+ host: config.reviewHost,
132
+ store: sessions,
133
+ logger,
134
+ reviewComputationDeps: {
135
+ validateAdapterLifecycle: validateSupportedAdapterLifecycle,
136
+ adapters: buildSupportedReviewAdapters({
137
+ deepbook: {
138
+ deepbookQuoteSource: readService,
139
+ deepbookDeepBalanceSource: async (account) => {
140
+ const balance = await suiClient.core.getBalance({
141
+ owner: account,
142
+ coinType: mainnetCoins.DEEP.type
143
+ });
144
+ return balance.balance.balance.toString();
145
+ },
146
+ deepbookTransactionMaterialProducer: createDeepbookSwapTransactionMaterialProducer({
147
+ client: suiClient,
148
+ network: config.network,
149
+ chainIdentifier,
150
+ expectedChainIdentifier: config.expectedChainIdentifier,
151
+ materialStore: transactionMaterialStore
152
+ }),
153
+ deepbookTransactionMaterialDigestProducer: createDeepbookSwapTransactionMaterialDigestProducer({
154
+ materialStore: transactionMaterialStore
155
+ }),
156
+ transactionObjectOwnershipProducer: createTransactionObjectOwnershipProducer({
157
+ materialStore: transactionMaterialStore,
158
+ objectSource: suiClient,
159
+ network: config.network,
160
+ chainIdentifier,
161
+ expectedChainIdentifier: config.expectedChainIdentifier
162
+ }),
163
+ deepbookHumanReadableReviewProducer: createDeepbookSwapHumanReadableReviewProducer(),
164
+ reviewTimeSimulationProducer: createReviewTimeSimulationProducer({
165
+ client: suiClient,
166
+ materialStore: transactionMaterialStore,
167
+ network: config.network,
168
+ chainIdentifier,
169
+ expectedChainIdentifier: config.expectedChainIdentifier
170
+ }),
171
+ ptbVisualizationProducer: (vizInput) => producePtbVisualizationArtifact({ materialStore: transactionMaterialStore, ...vizInput })
172
+ }
173
+ })
174
+ }
175
+ }).start(0);
176
+ const reviewBaseUrl = `http://${reviewServer.host}:${reviewServer.port}`;
177
+ server = createMcpServer({
178
+ sessions,
179
+ activityStore,
180
+ reviewBaseUrl,
181
+ localSettings,
182
+ readService,
183
+ transactionActivityService: new TransactionActivityService({
184
+ activityStore,
185
+ source: new GraphqlSuiTransactionActivitySource({
186
+ url: config.graphqlUrl,
187
+ expectedChainIdentifier: config.expectedChainIdentifier
188
+ })
189
+ }),
190
+ logger
191
+ });
192
+ await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);
193
+ const walletIdentity = await callSmokeTool(client, TOOL_NAMES.sessionCreateWalletIdentity, {});
194
+ const walletData = walletIdentity.data;
195
+ const walletSessionId = walletData?.walletSessionId ?? fail("tool_failure", "Wallet identity session id missing");
196
+ const walletUrl = walletData?.walletUrl ?? fail("tool_failure", "Wallet identity URL missing");
197
+ const walletToken = new URL(walletUrl).hash.slice(1);
198
+ if (!walletToken) {
199
+ fail("tool_failure", "Wallet identity token missing from wallet URL fragment");
200
+ }
201
+ markCompleted(TOOL_NAMES.sessionCreateWalletIdentity);
202
+ await postWalletLifecycle(reviewBaseUrl, walletSessionId, walletToken, "opened", {});
203
+ await postWalletLifecycle(reviewBaseUrl, walletSessionId, walletToken, "connecting", {});
204
+ await postWalletLifecycle(reviewBaseUrl, walletSessionId, walletToken, "result", {
205
+ status: "connected",
206
+ account: smokeAddress,
207
+ chain: "sui:mainnet",
208
+ walletName: "smoke"
209
+ });
210
+ const swapFromSymbol = process.env.SMOKE_SWAP_FROM_SYMBOL;
211
+ const swapToSymbol = process.env.SMOKE_SWAP_TO_SYMBOL;
212
+ const swapAmountDisplay = process.env.SMOKE_SWAP_AMOUNT_DISPLAY;
213
+ let accountBoundSwapReview = {
214
+ status: "not_run",
215
+ notRunReason: "missing_env",
216
+ requiredEnv: ["SMOKE_SWAP_FROM_SYMBOL", "SMOKE_SWAP_TO_SYMBOL", "SMOKE_SWAP_AMOUNT_DISPLAY"]
217
+ };
218
+ const swapEnvEntries = [
219
+ ["SMOKE_SWAP_FROM_SYMBOL", swapFromSymbol],
220
+ ["SMOKE_SWAP_TO_SYMBOL", swapToSymbol],
221
+ ["SMOKE_SWAP_AMOUNT_DISPLAY", swapAmountDisplay]
222
+ ];
223
+ const missingSwapEnv = swapEnvEntries.filter(([, value]) => value === undefined).map(([name]) => name);
224
+ if (missingSwapEnv.length > 0 && missingSwapEnv.length < swapEnvEntries.length) {
225
+ // A partial swap configuration is a misconfiguration, not an intentional skip.
226
+ fail("config_error", `Partial account-bound swap smoke configuration; missing: ${missingSwapEnv.join(", ")}`);
227
+ }
228
+ const rawSlippageEnv = process.env.SMOKE_SWAP_MAX_SLIPPAGE_BPS;
229
+ const maxSlippageBps = Number(rawSlippageEnv ?? "50");
230
+ if (rawSlippageEnv !== undefined && (!Number.isInteger(maxSlippageBps) || maxSlippageBps < 1)) {
231
+ fail("config_error", `SMOKE_SWAP_MAX_SLIPPAGE_BPS must be a positive integer, got: ${rawSlippageEnv}`);
232
+ }
233
+ if (swapFromSymbol !== undefined && swapToSymbol !== undefined && swapAmountDisplay !== undefined) {
234
+ const prepared = await callSmokeTool(client, TOOL_NAMES.actionPrepareSuiActionReview, {
235
+ intent: {
236
+ type: "swap",
237
+ from: { symbol: swapFromSymbol, amount: swapAmountDisplay },
238
+ to: { symbol: swapToSymbol },
239
+ maxSlippageBps
240
+ }
241
+ });
242
+ const preparedData = prepared.data;
243
+ const reviewSessionId = preparedData?.reviewSessionId ?? fail("tool_failure", "Swap review session id missing");
244
+ const reviewUrl = preparedData?.reviewUrl ?? fail("tool_failure", "Swap review URL missing");
245
+ const reviewToken = new URL(reviewUrl).hash.slice(1);
246
+ const planId = preparedData?.plans?.[0]?.id ?? fail("tool_failure", "Swap review plan id missing");
247
+ const stateResponse = await fetch(`${reviewBaseUrl}/api/review/${reviewSessionId}/state`, {
248
+ method: "POST",
249
+ headers: {
250
+ "content-type": "application/json",
251
+ "x-say-ur-intent-token": reviewToken,
252
+ origin: reviewBaseUrl
253
+ },
254
+ body: JSON.stringify({ planId, account: smokeAddress })
255
+ });
256
+ if (!stateResponse.ok) {
257
+ fail("tool_failure", `Account-bound swap review state failed: ${stateResponse.status} ${await stateResponse.text()}`);
258
+ }
259
+ const stateEnvelope = (await stateResponse.json());
260
+ const state = (stateEnvelope.state ?? stateEnvelope);
261
+ if (state.status === undefined) {
262
+ fail("tool_failure", "Account-bound swap review state shape missing status");
263
+ }
264
+ accountBoundSwapReview = {
265
+ status: "ok",
266
+ reviewStatus: state.status,
267
+ blockedReason: state.blockedReason,
268
+ completedStageCount: state.adapterLifecycle?.completedStages?.length ?? 0,
269
+ missingStages: state.adapterLifecycle?.missingStages ?? [],
270
+ contractEmitted: state.walletReviewAdapterContract !== undefined,
271
+ failedCheckIds: (state.checks ?? []).filter((check) => check.status === "fail").map((check) => check.id)
272
+ };
273
+ markCompleted("account_bound_swap_review");
274
+ }
275
+ const wallet = await callSmokeTool(client, TOOL_NAMES.readSummarizeWalletAssets, {});
276
+ const orderbook = await callSmokeTool(client, TOOL_NAMES.readInspectDeepbookOrderbook, {
277
+ poolKey,
278
+ ticks: 5
279
+ });
280
+ const quote = await callSmokeTool(client, TOOL_NAMES.readQuoteDeepbookAction, {
281
+ poolKey,
282
+ direction: "base_to_quote",
283
+ amountRaw: quoteAmount
284
+ });
285
+ const activityScan = await callSmokeTool(client, TOOL_NAMES.readScanSuiAccountActivity, {
286
+ account: smokeAddress,
287
+ limit: ACTIVITY_SMOKE_LIMIT
288
+ });
289
+ const activitySummary = await callSmokeTool(client, TOOL_NAMES.readSummarizeSuiActivityScan, {
290
+ limit: ACTIVITY_SMOKE_LIMIT
291
+ });
292
+ assertSmokeOkStatus(wallet, TOOL_NAMES.readSummarizeWalletAssets);
293
+ markCompleted(TOOL_NAMES.readSummarizeWalletAssets);
294
+ assertSmokeOkStatus(orderbook, TOOL_NAMES.readInspectDeepbookOrderbook);
295
+ markCompleted(TOOL_NAMES.readInspectDeepbookOrderbook);
296
+ assertSmokeOkStatus(quote, TOOL_NAMES.readQuoteDeepbookAction);
297
+ markCompleted(TOOL_NAMES.readQuoteDeepbookAction);
298
+ activitySmoke.scan = summarizeActivitySmokePayload(activityScan, TOOL_NAMES.readScanSuiAccountActivity, {
299
+ expectedAccountSource: "explicit_filter",
300
+ requireAnalysis: false,
301
+ expectNoDetails: true
302
+ });
303
+ markCompleted(TOOL_NAMES.readScanSuiAccountActivity);
304
+ activitySmoke.summary = summarizeActivitySmokePayload(activitySummary, TOOL_NAMES.readSummarizeSuiActivityScan, {
305
+ expectedAccountSource: "active_account_context",
306
+ requireAnalysis: true,
307
+ expectNoDetails: true
308
+ });
309
+ markCompleted(TOOL_NAMES.readSummarizeSuiActivityScan);
310
+ if (smokeFunctionTarget) {
311
+ const functionActivityScan = await callSmokeTool(client, TOOL_NAMES.readScanSuiFunctionActivity, {
312
+ function: smokeFunctionTarget,
313
+ account: smokeAddress,
314
+ limit: ACTIVITY_SMOKE_LIMIT
315
+ });
316
+ const functionActivitySummary = await callSmokeTool(client, TOOL_NAMES.readSummarizeSuiFunctionActivityScan, {
317
+ function: smokeFunctionTarget,
318
+ limit: ACTIVITY_SMOKE_LIMIT
319
+ });
320
+ functionActivitySmoke.scan = summarizeActivitySmokePayload(functionActivityScan, TOOL_NAMES.readScanSuiFunctionActivity, {
321
+ expectedAccountSource: "explicit_filter",
322
+ expectedRelationship: "sent",
323
+ requireFunction: true,
324
+ requireAnalysis: false,
325
+ expectNoDetails: true
326
+ });
327
+ markCompleted(TOOL_NAMES.readScanSuiFunctionActivity);
328
+ functionActivitySmoke.summary = summarizeActivitySmokePayload(functionActivitySummary, TOOL_NAMES.readSummarizeSuiFunctionActivityScan, {
329
+ expectedAccountSource: "active_account_context",
330
+ expectedRelationship: "sent",
331
+ requireFunction: true,
332
+ requireAnalysis: true,
333
+ expectNoDetails: true
334
+ });
335
+ markCompleted(TOOL_NAMES.readSummarizeSuiFunctionActivityScan);
336
+ }
337
+ if (inspectDigest) {
338
+ const inspected = await callSmokeTool(client, TOOL_NAMES.readInspectSuiTransaction, {
339
+ digest: inspectDigest,
340
+ account: smokeAddress
341
+ });
342
+ assertSmokeOkStatus(inspected, TOOL_NAMES.readInspectSuiTransaction);
343
+ markCompleted(TOOL_NAMES.readInspectSuiTransaction);
344
+ }
345
+ else if (inspectRandomLatest) {
346
+ const randomLatestDigest = await pickRandomLatestTransactionDigest({
347
+ url: config.graphqlUrl,
348
+ expectedChainIdentifier: config.expectedChainIdentifier
349
+ });
350
+ const inspected = await callSmokeTool(client, TOOL_NAMES.readInspectSuiTransaction, {
351
+ digest: randomLatestDigest
352
+ });
353
+ assertSmokeOkStatus(inspected, TOOL_NAMES.readInspectSuiTransaction);
354
+ markCompleted(TOOL_NAMES.readInspectSuiTransaction);
355
+ }
356
+ tryWriteSmokeResult({
357
+ accountBoundSwapReview,
358
+ ok: true,
359
+ startedAt: startedAt.toISOString(),
360
+ completedAt: new Date().toISOString(),
361
+ chainIdentifier,
362
+ env: smokeEnvPresence(),
363
+ plannedTools: [...plannedTools],
364
+ attemptedTools,
365
+ tools: completedTools,
366
+ activitySmoke,
367
+ functionActivitySmoke
368
+ });
369
+ process.stdout.write(`${JSON.stringify({
370
+ ok: true,
371
+ plannedTools: [...plannedTools],
372
+ attemptedTools,
373
+ tools: completedTools,
374
+ activitySmoke,
375
+ functionActivitySmoke
376
+ }, null, 2)}\n`);
377
+ }
378
+ finally {
379
+ activityStore?.close();
380
+ if (smokeDbDir) {
381
+ rmSync(smokeDbDir, { recursive: true, force: true });
382
+ }
383
+ await Promise.allSettled([
384
+ ...(server ? [server.close()] : []),
385
+ client.close(),
386
+ ...(reviewServer ? [reviewServer.close()] : [])
387
+ ]);
388
+ }
389
+ }
390
+ async function callSmokeTool(client, name, args) {
391
+ attemptedTools.push(name);
392
+ return callTool(client, name, args);
393
+ }
394
+ async function callTool(client, name, args) {
395
+ const result = await client.callTool({ name, arguments: args });
396
+ const content = result.content;
397
+ const text = content[0]?.type === "text" ? content[0].text : undefined;
398
+ if (!text) {
399
+ fail("tool_failure", `Tool ${name} did not return text JSON content`);
400
+ }
401
+ try {
402
+ return JSON.parse(text);
403
+ }
404
+ catch (error) {
405
+ throw new SmokeResponseShapeError(`Tool ${name} did not return valid text JSON content: ${error instanceof Error ? error.message : String(error)}`);
406
+ }
407
+ }
408
+ function markCompleted(name) {
409
+ if (!completedTools.includes(name)) {
410
+ completedTools.push(name);
411
+ }
412
+ }
413
+ function requiredEnv(name) {
414
+ const value = process.env[name];
415
+ if (!value) {
416
+ fail("missing_env", `${name} is required for npm run smoke:mainnet`);
417
+ }
418
+ return value;
419
+ }
420
+ function truthyEnv(name) {
421
+ const value = process.env[name];
422
+ return value === "1" || value === "true" || value === "TRUE" || value === "yes" || value === "YES";
423
+ }
424
+ async function pickRandomLatestTransactionDigest(input) {
425
+ const { client } = await verifyMainnetGraphqlEndpoint({
426
+ url: input.url,
427
+ expectedChainIdentifier: input.expectedChainIdentifier
428
+ });
429
+ const result = await client.query({
430
+ query: `
431
+ query SayUrIntentSmokeLatestTransactionSample($last: Int!) {
432
+ transactions(last: $last) {
433
+ nodes { digest }
434
+ }
435
+ }
436
+ `,
437
+ variables: { last: 20 }
438
+ });
439
+ if (result.errors && result.errors.length > 0) {
440
+ fail("tool_failure", `Latest transaction sample query failed: ${result.errors.map((error) => error.message).join("; ")}`);
441
+ }
442
+ const digests = result.data?.transactions?.nodes
443
+ ?.flatMap((node) => typeof node.digest === "string" && node.digest.length > 0 ? [node.digest] : []) ?? [];
444
+ if (digests.length === 0) {
445
+ fail("tool_failure", "Latest transaction sample query returned no transaction digests");
446
+ }
447
+ return digests[randomInt(digests.length)] ?? fail("tool_failure", "Latest transaction sample selection failed");
448
+ }
449
+ function loadSmokeBootConfig() {
450
+ try {
451
+ return loadBootConfig();
452
+ }
453
+ catch (error) {
454
+ throw new SmokeMainnetError("config_error", error instanceof Error ? error.message : String(error));
455
+ }
456
+ }
457
+ function fail(category, message) {
458
+ throw new SmokeMainnetError(category, message);
459
+ }
460
+ function smokeEnvPresence() {
461
+ return {
462
+ SUI_GRPC_URL: process.env.SUI_GRPC_URL !== undefined,
463
+ SUI_GRAPHQL_URL: process.env.SUI_GRAPHQL_URL !== undefined,
464
+ SMOKE_SUI_ADDRESS: process.env.SMOKE_SUI_ADDRESS !== undefined,
465
+ SMOKE_DEEPBOOK_POOL_KEY: process.env.SMOKE_DEEPBOOK_POOL_KEY !== undefined,
466
+ SMOKE_QUOTE_AMOUNT: process.env.SMOKE_QUOTE_AMOUNT !== undefined,
467
+ SMOKE_INSPECT_DIGEST: process.env.SMOKE_INSPECT_DIGEST !== undefined,
468
+ SMOKE_INSPECT_RANDOM_LATEST: process.env.SMOKE_INSPECT_RANDOM_LATEST !== undefined,
469
+ SMOKE_FUNCTION_TARGET: process.env.SMOKE_FUNCTION_TARGET !== undefined,
470
+ SMOKE_SWAP_FROM_SYMBOL: process.env.SMOKE_SWAP_FROM_SYMBOL !== undefined,
471
+ SMOKE_SWAP_TO_SYMBOL: process.env.SMOKE_SWAP_TO_SYMBOL !== undefined,
472
+ SMOKE_SWAP_AMOUNT_DISPLAY: process.env.SMOKE_SWAP_AMOUNT_DISPLAY !== undefined
473
+ };
474
+ }
475
+ async function postWalletLifecycle(baseUrl, walletSessionId, token, event, body) {
476
+ const response = await fetch(`${baseUrl}/api/wallet/${walletSessionId}/${event}`, {
477
+ method: "POST",
478
+ headers: {
479
+ "content-type": "application/json",
480
+ "x-say-ur-intent-token": token,
481
+ origin: baseUrl
482
+ },
483
+ body: JSON.stringify(body)
484
+ });
485
+ if (!response.ok) {
486
+ fail("tool_failure", `Wallet identity smoke ${event} failed: ${response.status}`);
487
+ }
488
+ }
489
+ function tryWriteSmokeResult(record) {
490
+ try {
491
+ writeSmokeResult(record);
492
+ }
493
+ catch (error) {
494
+ process.stderr.write(`smoke:mainnet result recording failed: ${error instanceof Error ? error.message : String(error)}\n`);
495
+ }
496
+ }
497
+ function writeSmokeResult(record) {
498
+ const directory = join(process.cwd(), ".WORK", "smoke-results");
499
+ mkdirSync(directory, { recursive: true });
500
+ writeFileSync(join(directory, `${record.completedAt ?? new Date().toISOString()}.json`.replace(/:/g, "-")), `${JSON.stringify(record, null, 2)}\n`);
501
+ }
502
+ function smokeErrorCategory(error) {
503
+ if (error instanceof SuiEndpointError) {
504
+ return error.kind;
505
+ }
506
+ if (error instanceof SmokeResponseShapeError) {
507
+ return "tool_failure";
508
+ }
509
+ if (error instanceof SmokeMainnetError) {
510
+ return error.category;
511
+ }
512
+ return "runtime_error";
513
+ }
514
+ main().catch((error) => {
515
+ tryWriteSmokeResult({
516
+ ok: false,
517
+ startedAt: startedAt.toISOString(),
518
+ completedAt: new Date().toISOString(),
519
+ env: smokeEnvPresence(),
520
+ attemptedTools,
521
+ tools: completedTools,
522
+ plannedTools: [...plannedTools],
523
+ activitySmoke,
524
+ functionActivitySmoke,
525
+ errorCategory: smokeErrorCategory(error)
526
+ });
527
+ process.stderr.write(`smoke:mainnet failed: ${error instanceof Error ? error.message : String(error)}\n`);
528
+ process.exit(1);
529
+ });