@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.
- package/README.md +4 -39
- package/dist/adapters/adapterLifecycleValidators.js +7 -0
- package/dist/adapters/adapterPromptSurfaces.js +71 -0
- package/dist/adapters/deepbook/deepbookHumanReviewProducer.js +175 -0
- package/dist/adapters/deepbook/deepbookQuotePolicy.js +112 -0
- package/dist/adapters/deepbook/deepbookReviewEvidence.js +507 -0
- package/dist/adapters/deepbook/deepbookReviewLifecycle.js +85 -0
- package/dist/adapters/deepbook/deepbookSwapIntent.js +79 -0
- package/dist/adapters/deepbook/deepbookTransactionMaterialProducer.js +269 -0
- package/dist/adapters/flowx/flowxSwapHumanReviewProducer.js +176 -0
- package/dist/adapters/flowx/flowxSwapIntent.js +79 -0
- package/dist/adapters/flowx/flowxSwapQuotePolicy.js +104 -0
- package/dist/adapters/flowx/flowxSwapReviewEvidence.js +468 -0
- package/dist/adapters/flowx/flowxSwapReviewLifecycle.js +85 -0
- package/dist/adapters/flowx/flowxSwapTransactionMaterialProducer.js +362 -0
- package/dist/adapters/intentPlanFactories.js +59 -0
- package/dist/adapters/reviewAdapters.js +81 -0
- package/dist/core/action/adapterLifecycleValidation.js +12 -0
- package/dist/core/action/forbiddenFields.js +43 -0
- package/dist/core/action/humanReadableReviewEvidence.js +203 -0
- package/dist/core/action/humanReadableReviewProjectionVerifier.js +29 -0
- package/dist/core/action/ptbVisualizationProducer.js +66 -0
- package/dist/core/action/reviewCheckResults.js +6 -0
- package/dist/core/action/reviewStateValidation.js +11 -0
- package/dist/core/action/reviewTimeSimulationEvidence.js +471 -0
- package/dist/core/action/schemas.js +529 -0
- package/dist/core/action/signableAdapterContract.js +993 -0
- package/dist/core/action/swapHumanReadableReviewProjection.js +124 -0
- package/dist/core/action/swapQuotePolicyEvidence.js +278 -0
- package/dist/core/action/transactionObjectOwnershipEvidence.js +247 -0
- package/dist/core/action/transactionObjectOwnershipProducer.js +329 -0
- package/dist/core/action/types.js +35 -0
- package/dist/core/action/walletReviewContractAssembler.js +282 -0
- package/dist/core/activity/activityStore.js +15 -0
- package/dist/core/activity/localDataService.js +258 -0
- package/dist/core/activity/localDataTypes.js +11 -0
- package/dist/core/activity/localDataValidation.js +396 -0
- package/dist/core/activity/schemaVersion.js +1 -0
- package/dist/core/activity/sqliteActivityStore.js +820 -0
- package/dist/core/activity/sqliteActivityStoreRows.js +430 -0
- package/dist/core/activity/sqliteActivityStoreSchema.js +258 -0
- package/dist/core/activity/sqliteActivityStoreTypes.js +5 -0
- package/dist/core/activity/suiFunctionTarget.js +43 -0
- package/dist/core/activity/transactionActivityAccountEffects.js +189 -0
- package/dist/core/activity/transactionActivityAnalysis.js +295 -0
- package/dist/core/activity/transactionActivityClassifier.js +306 -0
- package/dist/core/activity/transactionActivityDetails.js +229 -0
- package/dist/core/activity/transactionActivityProtocolRules.js +218 -0
- package/dist/core/activity/transactionActivityScanPolicy.js +170 -0
- package/dist/core/activity/transactionActivityService.js +379 -0
- package/dist/core/activity/transactionActivityTypes.js +18 -0
- package/dist/core/eventlog/sink.js +35 -0
- package/dist/core/evidence/settlementFamilies.js +87 -0
- package/dist/core/evidence/userAnswerUse.js +1 -0
- package/dist/core/numeric/rawU64.js +63 -0
- package/dist/core/preferences/preferencesStore.js +26 -0
- package/dist/core/preferences/sqlitePreferencesRepository.js +136 -0
- package/dist/core/proposal/externalProposalReview.js +347 -0
- package/dist/core/proposal/schemas.js +208 -0
- package/dist/core/proposal/types.js +35 -0
- package/dist/core/read/amounts.js +14 -0
- package/dist/core/read/coinMetadata.js +60 -0
- package/dist/core/read/deepbookRawQuoteClient.js +86 -0
- package/dist/core/read/deepbookReadHelpers.js +265 -0
- package/dist/core/read/deepbookRegistry.js +133 -0
- package/dist/core/read/flowxQuoteClient.js +117 -0
- package/dist/core/read/flowxReadHelpers.js +145 -0
- package/dist/core/read/flowxRegistry.js +174 -0
- package/dist/core/read/intentEvidenceResponseFormatting.js +228 -0
- package/dist/core/read/readResponseGuidance.js +451 -0
- package/dist/core/read/readService.js +1164 -0
- package/dist/core/read/readServiceTypes.js +59 -0
- package/dist/core/read/settlementParityFormatting.js +82 -0
- package/dist/core/read/walletReadHelpers.js +99 -0
- package/dist/core/review/reviewChecks.js +54 -0
- package/dist/core/review/reviewComputation.js +38 -0
- package/dist/core/review/reviewComputationResult.js +87 -0
- package/dist/core/session/localSession.js +31 -0
- package/dist/core/session/privateReviewArtifacts.js +73 -0
- package/dist/core/session/sessionErrors.js +9 -0
- package/dist/core/session/sessionStore.js +821 -0
- package/dist/core/session/settingsSession.js +1 -0
- package/dist/core/session/settingsSessions.js +43 -0
- package/dist/core/session/status.js +86 -0
- package/dist/core/session/transactionMaterialStore.js +205 -0
- package/dist/core/session/wait.js +102 -0
- package/dist/core/session/walletIdentity.js +103 -0
- package/dist/core/session/walletIdentitySessions.js +189 -0
- package/dist/core/suiAddress.js +18 -0
- package/dist/core/suiEndpoint.js +72 -0
- package/dist/mcp/activeAccountResponse.js +24 -0
- package/dist/mcp/prompts.js +146 -0
- package/dist/mcp/registerTool.js +19 -0
- package/dist/mcp/resources.js +72 -0
- package/dist/mcp/responseGuidance.js +381 -0
- package/dist/mcp/result.js +17 -0
- package/dist/mcp/schemas.js +8 -0
- package/dist/mcp/server.js +30 -0
- package/dist/mcp/serverInfo.js +123 -0
- package/dist/mcp/toolErrors.js +105 -0
- package/dist/mcp/toolNames.js +50 -0
- package/dist/mcp/tools/account/index.js +44 -0
- package/dist/mcp/tools/action/prepareSuiActionReview.js +120 -0
- package/dist/mcp/tools/read/commonSchemas.js +43 -0
- package/dist/mcp/tools/read/deepbookReadTools.js +453 -0
- package/dist/mcp/tools/read/flowxReadTools.js +135 -0
- package/dist/mcp/tools/read/index.js +16 -0
- package/dist/mcp/tools/read/readToolHelpers.js +68 -0
- package/dist/mcp/tools/read/reviewActivityTools.js +176 -0
- package/dist/mcp/tools/read/serverStatusTools.js +103 -0
- package/dist/mcp/tools/read/transactionActivityOutput.js +300 -0
- package/dist/mcp/tools/read/transactionActivityTools.js +544 -0
- package/dist/mcp/tools/read/walletReadTools.js +733 -0
- package/dist/mcp/tools/session/executionResultTools.js +92 -0
- package/dist/mcp/tools/session/index.js +8 -0
- package/dist/mcp/tools/session/shared.js +79 -0
- package/dist/mcp/tools/session/statusTools.js +134 -0
- package/dist/mcp/tools/session/walletIdentityTools.js +119 -0
- package/dist/mcp/tools/settings/index.js +64 -0
- package/dist/review-app/analysis.css +1 -0
- package/dist/review-app/analysis.js +1 -0
- package/dist/review-app/arc-BjIacwQm.js +1 -0
- package/dist/review-app/architecture-U656AL7Q-aSB9x1OK.js +1 -0
- package/dist/review-app/architectureDiagram-VXUJARFQ-C5W6re2I.js +36 -0
- package/dist/review-app/array-BmXUUrU6.js +1 -0
- package/dist/review-app/blockDiagram-VD42YOAC-20MLNcUm.js +122 -0
- package/dist/review-app/c4Diagram-YG6GDRKO-BZXRrcck.js +10 -0
- package/dist/review-app/channel-lk2p_CUu.js +1 -0
- package/dist/review-app/chunk-4BX2VUAB-BPITOdjX.js +1 -0
- package/dist/review-app/chunk-55IACEB6-Dz-pyw5k.js +1 -0
- package/dist/review-app/chunk-76Q3JFCE-cK_X1P_l.js +1 -0
- package/dist/review-app/chunk-ABZYJK2D-Dt4W53JI.js +81 -0
- package/dist/review-app/chunk-ATLVNIR6-fZHLXURb.js +1 -0
- package/dist/review-app/chunk-B4BG7PRW-BbgcjusC.js +165 -0
- package/dist/review-app/chunk-BJD4TVEz.js +1 -0
- package/dist/review-app/chunk-CVBHYZKI-CViawAKX.js +1 -0
- package/dist/review-app/chunk-DI55MBZ5-C5aoul-d.js +220 -0
- package/dist/review-app/chunk-FMBD7UC4-Chxmw62A.js +15 -0
- package/dist/review-app/chunk-FPAJGGOC-DDHjQ09H.js +80 -0
- package/dist/review-app/chunk-FWNWRKHM-CVVQUptk.js +1 -0
- package/dist/review-app/chunk-HN2XXSSU-yzNpjaSZ.js +1 -0
- package/dist/review-app/chunk-JA3XYJ7Z-C5ZJdU01.js +70 -0
- package/dist/review-app/chunk-JZLCHNYA-BBST4Cnk.js +54 -0
- package/dist/review-app/chunk-LBM3YZW2-CdwAPuHr.js +1 -0
- package/dist/review-app/chunk-LHMN2FUI-BtB5uDcp.js +1 -0
- package/dist/review-app/chunk-O7ZBX7Z2-pxdK4Sa3.js +1 -0
- package/dist/review-app/chunk-QN33PNHL-CbVv3uGK.js +1 -0
- package/dist/review-app/chunk-QXUST7PY-DKM2-t2c.js +7 -0
- package/dist/review-app/chunk-QZHKN3VN-C5ni2pN_.js +1 -0
- package/dist/review-app/chunk-S3R3BYOJ-BWvOhDs0.js +2 -0
- package/dist/review-app/chunk-S6J4BHB3-D9Fk0YeD.js +1 -0
- package/dist/review-app/chunk-T53DSG4Q-C1qEyzyV.js +1 -0
- package/dist/review-app/chunk-TZMSLE5B-B--7eU69.js +1 -0
- package/dist/review-app/classDiagram-2ON5EDUG-DlL1m2bp.js +1 -0
- package/dist/review-app/classDiagram-v2-WZHVMYZB-FXRskT1j.js +1 -0
- package/dist/review-app/clone-BZZb7gpZ.js +1 -0
- package/dist/review-app/cose-bilkent-S5V4N54A-CRIb8XEO.js +1 -0
- package/dist/review-app/cytoscape.esm-C7jYqDP5.js +321 -0
- package/dist/review-app/dagre-6UL2VRFP-FNCAXbdE.js +4 -0
- package/dist/review-app/dagre-Be46QtUd.js +1 -0
- package/dist/review-app/defaultLocale-BaWNtAUL.js +1 -0
- package/dist/review-app/diagram-PSM6KHXK-ylLWjiNM.js +24 -0
- package/dist/review-app/diagram-QEK2KX5R-BCDcESxs.js +43 -0
- package/dist/review-app/diagram-S2PKOQOG-Vdrc-vrO.js +24 -0
- package/dist/review-app/dist-WPc74x_f.js +1 -0
- package/dist/review-app/erDiagram-Q2GNP2WA-E5ZsUbDF.js +60 -0
- package/dist/review-app/flatten-DHf9IeNI.js +1 -0
- package/dist/review-app/flowDiagram-NV44I4VS-DBSQuj6x.js +162 -0
- package/dist/review-app/ganttDiagram-LVOFAZNH-CKUOsqwl.js +267 -0
- package/dist/review-app/gitGraph-F6HP7TQM-DsAD6qK1.js +1 -0
- package/dist/review-app/gitGraphDiagram-NY62KEGX-BCeIMWdl.js +65 -0
- package/dist/review-app/graphlib-CiX5CXxR.js +1 -0
- package/dist/review-app/http-DMvwuuFk.js +1 -0
- package/dist/review-app/identity-DY8PXc6t.js +1 -0
- package/dist/review-app/info-NVLQJR56-Dlx1nZic.js +1 -0
- package/dist/review-app/infoDiagram-F6ZHWCRC-CAuANIrz.js +2 -0
- package/dist/review-app/init-BvqephKz.js +1 -0
- package/dist/review-app/journeyDiagram-XKPGCS4Q-C-Z9phnx.js +139 -0
- package/dist/review-app/kanban-definition-3W4ZIXB7-DufgZABq.js +89 -0
- package/dist/review-app/katex-B-Z-NXXN.js +257 -0
- package/dist/review-app/line-DiIv3Jgw.js +1 -0
- package/dist/review-app/linear-Cv-UPvo1.js +1 -0
- package/dist/review-app/math-kmyYrkHL.js +1 -0
- package/dist/review-app/mermaid-parser.core-DkwUYTPl.js +4 -0
- package/dist/review-app/mindmap-definition-VGOIOE7T-TM_CqdmV.js +68 -0
- package/dist/review-app/ordinal-BliTlkoG.js +1 -0
- package/dist/review-app/packet-BFZMPI3H-DqbnU92v.js +1 -0
- package/dist/review-app/path-AEo9W6mQ.js +1 -0
- package/dist/review-app/pie-7BOR55EZ-LJzaLkgr.js +1 -0
- package/dist/review-app/pieDiagram-ADFJNKIX-BAs8OfRS.js +30 -0
- package/dist/review-app/quadrantDiagram-AYHSOK5B-CyUDZP5S.js +7 -0
- package/dist/review-app/radar-NHE76QYJ-DBpHc8_Y.js +1 -0
- package/dist/review-app/reduce-B-HuPpdd.js +1 -0
- package/dist/review-app/requirementDiagram-UZGBJVZJ-BEHix78P.js +64 -0
- package/dist/review-app/review.css +1 -0
- package/dist/review-app/review.js +43 -0
- package/dist/review-app/sankeyDiagram-TZEHDZUN-B2bKbmsm.js +10 -0
- package/dist/review-app/sequenceDiagram-WL72ISMW-DVLOORFJ.js +145 -0
- package/dist/review-app/settings.css +1 -0
- package/dist/review-app/settings.js +1 -0
- package/dist/review-app/src-Buml7cM5.js +1 -0
- package/dist/review-app/stateDiagram-FKZM4ZOC-sFGGp2kV.js +1 -0
- package/dist/review-app/stateDiagram-v2-4FDKWEC3-BHfCF4dX.js +1 -0
- package/dist/review-app/timeline-definition-IT6M3QCI-BESnBijC.js +61 -0
- package/dist/review-app/treemap-KMMF4GRG-wnVLBDeQ.js +1 -0
- package/dist/review-app/walletStatus-CcojOdGy.js +7 -0
- package/dist/review-app/xychartDiagram-PRI3JC2R-BGWVfCx4.js +7 -0
- package/dist/review-server/assets.js +48 -0
- package/dist/review-server/html.js +66 -0
- package/dist/review-server/http.js +47 -0
- package/dist/review-server/middleware/hostOrigin.js +48 -0
- package/dist/review-server/middleware/reviewToken.js +7 -0
- package/dist/review-server/reviewServerPolicy.js +10 -0
- package/dist/review-server/server.js +568 -0
- package/dist/review-server/settingsApi.js +182 -0
- package/dist/review-server/walletIdentityResponse.js +13 -0
- package/dist/runtime/config.js +103 -0
- package/dist/runtime/localSettingsService.js +198 -0
- package/dist/runtime/logger.js +50 -0
- package/dist/runtime/reviewServerAcquire.js +128 -0
- package/dist/runtime/smokeMainnetRead.js +529 -0
- package/dist/runtime/smokeMainnetReadAssertions.js +308 -0
- package/dist/runtime/start.js +295 -0
- package/dist/runtime/suiEndpoint.js +97 -0
- package/dist/runtime/suiTransactionGraphqlMapping.js +200 -0
- package/dist/runtime/suiTransactionGraphqlQueries.js +231 -0
- package/dist/runtime/suiTransactionGraphqlSource.js +148 -0
- package/docs/AGENT_BEHAVIOR.md +1 -1
- package/docs/AGENT_DEVELOPMENT_POLICY.md +20 -0
- package/docs/FRONTEND_POLICY.md +4 -3
- package/docs/MCP_SETUP.md +59 -7
- package/docs/MCP_TOOLS.md +1 -1
- package/docs/SDK_API.md +5 -1
- package/package.json +3 -2
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
export class SmokeResponseShapeError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "SmokeResponseShapeError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export function assertSmokeOkStatus(payload, toolName) {
|
|
8
|
+
const data = objectValue(payload.data);
|
|
9
|
+
if (payload.ok !== true || data?.status !== "ok") {
|
|
10
|
+
throw new SmokeResponseShapeError(`Tool ${toolName} did not return ok status: ${JSON.stringify(payload)}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function summarizeActivitySmokePayload(payload, toolName, options) {
|
|
14
|
+
assertSmokeOkStatus(payload, toolName);
|
|
15
|
+
const data = requiredObject(payload.data, `${toolName}.data`);
|
|
16
|
+
const source = requiredObject(data.source, `${toolName}.data.source`);
|
|
17
|
+
const persistence = requiredObject(data.persistence, `${toolName}.data.persistence`);
|
|
18
|
+
const requestedAccount = requiredObject(data.requestedAccount, `${toolName}.data.requestedAccount`);
|
|
19
|
+
const transactions = requiredArray(data.transactions, `${toolName}.data.transactions`);
|
|
20
|
+
const account = requiredString(data.account, `${toolName}.data.account`);
|
|
21
|
+
const accountSource = requiredAccountSource(data.accountSource, `${toolName}.data.accountSource`);
|
|
22
|
+
const relationship = requiredRelationship(data.relationship, `${toolName}.data.relationship`);
|
|
23
|
+
const functionTarget = options.requireFunction
|
|
24
|
+
? requiredString(data.function, `${toolName}.data.function`)
|
|
25
|
+
: undefined;
|
|
26
|
+
const sourceTransport = requiredLiteral(source.transport, "graphql", `${toolName}.data.source.transport`);
|
|
27
|
+
const sourceMethod = requiredLiteral(source.method, "Query.transactions", `${toolName}.data.source.method`);
|
|
28
|
+
const hasMore = requiredBoolean(data.hasMore, `${toolName}.data.hasMore`);
|
|
29
|
+
const windowComplete = requiredBooleanOrNull(data.windowComplete, `${toolName}.data.windowComplete`);
|
|
30
|
+
const orderingVerified = requiredBoolean(data.orderingVerified, `${toolName}.data.orderingVerified`);
|
|
31
|
+
const persistenceStored = requiredBoolean(persistence.stored, `${toolName}.data.persistence.stored`);
|
|
32
|
+
const requestedAccountBalanceChangeCompleteness = requiredBalanceChangeCompleteness(requestedAccount.balanceChangeCompleteness, `${toolName}.data.requestedAccount.balanceChangeCompleteness`);
|
|
33
|
+
const requestedAccountCoinFlows = requiredArray(requestedAccount.coinFlows, `${toolName}.data.requestedAccount.coinFlows`);
|
|
34
|
+
const requestedAccountSentCount = requiredNonnegativeInteger(requestedAccount.sentCount, `${toolName}.data.requestedAccount.sentCount`);
|
|
35
|
+
const requestedAccountAffectedOnlyCount = requiredNonnegativeInteger(requestedAccount.affectedOnlyCount, `${toolName}.data.requestedAccount.affectedOnlyCount`);
|
|
36
|
+
const requestedAccountTransactionFacts = requiredArray(data.requestedAccountTransactionFacts, `${toolName}.data.requestedAccountTransactionFacts`);
|
|
37
|
+
const accountFactSummary = summarizeRequestedAccountTransactionFacts(requestedAccountTransactionFacts, transactions.length, toolName);
|
|
38
|
+
const compactSummary = summarizeCompactResponseSupport(transactions, toolName);
|
|
39
|
+
let analysisLimitationCount;
|
|
40
|
+
let analysisCoinFlowCount;
|
|
41
|
+
if (accountSource !== options.expectedAccountSource) {
|
|
42
|
+
throw new SmokeResponseShapeError(`${toolName}.data.accountSource expected ${options.expectedAccountSource}, got ${accountSource}`);
|
|
43
|
+
}
|
|
44
|
+
if (options.expectedRelationship !== undefined && relationship !== options.expectedRelationship) {
|
|
45
|
+
throw new SmokeResponseShapeError(`${toolName}.data.relationship expected ${options.expectedRelationship}, got ${relationship}`);
|
|
46
|
+
}
|
|
47
|
+
if (options.requireAnalysis) {
|
|
48
|
+
const analysis = requiredObject(data.analysis, `${toolName}.data.analysis`);
|
|
49
|
+
const overview = requiredObject(analysis.overview, `${toolName}.data.analysis.overview`);
|
|
50
|
+
const limitations = requiredArray(analysis.limitations, `${toolName}.data.analysis.limitations`);
|
|
51
|
+
const coinFlows = requiredArray(analysis.coinFlows, `${toolName}.data.analysis.coinFlows`);
|
|
52
|
+
const analysisTransactionCount = requiredNonnegativeInteger(overview.transactionCount, `${toolName}.data.analysis.overview.transactionCount`);
|
|
53
|
+
if (analysisTransactionCount !== transactions.length) {
|
|
54
|
+
throw new SmokeResponseShapeError(`${toolName}.data.analysis.overview.transactionCount does not match transactions.length`);
|
|
55
|
+
}
|
|
56
|
+
analysisLimitationCount = limitations.length;
|
|
57
|
+
analysisCoinFlowCount = coinFlows.length;
|
|
58
|
+
}
|
|
59
|
+
if (options.expectNoDetails === true && compactSummary.fullDetailsReturned) {
|
|
60
|
+
throw new SmokeResponseShapeError(`${toolName}.data.transactions must not include full details`);
|
|
61
|
+
}
|
|
62
|
+
if (options.expectNoDetails === true && compactSummary.compactReturned) {
|
|
63
|
+
throw new SmokeResponseShapeError(`${toolName}.data.transactions must not include compact transaction aggregates`);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
status: transactions.length === 0 ? "empty_page" : "ok",
|
|
67
|
+
rowCount: transactions.length,
|
|
68
|
+
emptyAccepted: transactions.length === 0,
|
|
69
|
+
transactionCount: transactions.length,
|
|
70
|
+
account,
|
|
71
|
+
accountSource,
|
|
72
|
+
relationship,
|
|
73
|
+
...(functionTarget === undefined ? {} : { functionTargetPresent: true }),
|
|
74
|
+
sourceTransport,
|
|
75
|
+
sourceMethod,
|
|
76
|
+
hasMore,
|
|
77
|
+
windowComplete,
|
|
78
|
+
orderingVerified,
|
|
79
|
+
persistenceStored,
|
|
80
|
+
requestedAccountBalanceChangeCompleteness,
|
|
81
|
+
requestedAccountCoinFlowCount: requestedAccountCoinFlows.length,
|
|
82
|
+
requestedAccountSentCount,
|
|
83
|
+
requestedAccountAffectedOnlyCount,
|
|
84
|
+
...accountFactSummary,
|
|
85
|
+
...compactSummary,
|
|
86
|
+
...(analysisLimitationCount === undefined ? {} : { analysisLimitationCount }),
|
|
87
|
+
...(analysisCoinFlowCount === undefined ? {} : { analysisCoinFlowCount })
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function summarizeRequestedAccountTransactionFacts(facts, transactionCount, toolName) {
|
|
91
|
+
if (facts.length !== transactionCount) {
|
|
92
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts length does not match transactions.length`);
|
|
93
|
+
}
|
|
94
|
+
let balanceChangeRows = 0;
|
|
95
|
+
facts.forEach((factValue, factIndex) => {
|
|
96
|
+
const fact = requiredObject(factValue, `${toolName}.data.requestedAccountTransactionFacts[${factIndex}]`);
|
|
97
|
+
const requestedAccountEffect = requiredObject(fact.requestedAccountEffect, `${toolName}.data.requestedAccountTransactionFacts[${factIndex}].requestedAccountEffect`);
|
|
98
|
+
const evidence = requiredAccountBalanceChangeEvidence(fact.accountBalanceChangeEvidence, `${toolName}.data.requestedAccountTransactionFacts[${factIndex}].accountBalanceChangeEvidence`);
|
|
99
|
+
const absenceProven = requiredBoolean(fact.accountBalanceChangeAbsenceProven, `${toolName}.data.requestedAccountTransactionFacts[${factIndex}].accountBalanceChangeAbsenceProven`);
|
|
100
|
+
const inferencePolicy = requiredAccountBalanceChangeInferencePolicy(fact.accountBalanceChangeInferencePolicy, `${toolName}.data.requestedAccountTransactionFacts[${factIndex}].accountBalanceChangeInferencePolicy`);
|
|
101
|
+
const completeness = requiredBalanceChangeCompleteness(fact.accountBalanceChangeCompleteness, `${toolName}.data.requestedAccountTransactionFacts[${factIndex}].accountBalanceChangeCompleteness`);
|
|
102
|
+
requiredLiteral(requestedAccountEffect.scope, "requested_account", `${toolName}.data.requestedAccountTransactionFacts[${factIndex}].requestedAccountEffect.scope`);
|
|
103
|
+
const balanceChanges = requiredArray(fact.accountBalanceChanges, `${toolName}.data.requestedAccountTransactionFacts[${factIndex}].accountBalanceChanges`);
|
|
104
|
+
balanceChangeRows += balanceChanges.length;
|
|
105
|
+
const nestedBalanceChanges = requiredArray(requestedAccountEffect.balanceChanges, `${toolName}.data.requestedAccountTransactionFacts[${factIndex}].requestedAccountEffect.balanceChanges`);
|
|
106
|
+
if (nestedBalanceChanges.length !== balanceChanges.length) {
|
|
107
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}] accountBalanceChanges length must match requestedAccountEffect.balanceChanges length`);
|
|
108
|
+
}
|
|
109
|
+
if (completeness === "truncated" && evidence !== "incomplete_account_balance_changes") {
|
|
110
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}] truncated account evidence must be incomplete_account_balance_changes`);
|
|
111
|
+
}
|
|
112
|
+
if (completeness === "unavailable" && evidence !== "account_balance_changes_unavailable") {
|
|
113
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}] unavailable account evidence must be account_balance_changes_unavailable`);
|
|
114
|
+
}
|
|
115
|
+
if (completeness === "complete" && balanceChanges.length === 0 && evidence !== "no_account_balance_changes_returned") {
|
|
116
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}] empty complete account evidence must be no_account_balance_changes_returned`);
|
|
117
|
+
}
|
|
118
|
+
const expectedAbsenceProven = completeness === "complete" && balanceChanges.length === 0;
|
|
119
|
+
if (absenceProven !== expectedAbsenceProven) {
|
|
120
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}].accountBalanceChangeAbsenceProven is inconsistent with evidence completeness and row count`);
|
|
121
|
+
}
|
|
122
|
+
if (requestedAccountEffect.accountBalanceChangeAbsenceProven !== absenceProven) {
|
|
123
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}].requestedAccountEffect.accountBalanceChangeAbsenceProven does not match flat field`);
|
|
124
|
+
}
|
|
125
|
+
const expectedInferencePolicy = expectedAccountBalanceChangeInferencePolicy(evidence, absenceProven);
|
|
126
|
+
if (inferencePolicy !== expectedInferencePolicy) {
|
|
127
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}].accountBalanceChangeInferencePolicy is inconsistent with account evidence`);
|
|
128
|
+
}
|
|
129
|
+
if (requestedAccountEffect.accountBalanceChangeInferencePolicy !== inferencePolicy) {
|
|
130
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}].requestedAccountEffect.accountBalanceChangeInferencePolicy does not match flat field`);
|
|
131
|
+
}
|
|
132
|
+
const transactionContext = objectValue(fact.transactionContext);
|
|
133
|
+
if (transactionContext !== undefined && Object.hasOwn(transactionContext, "balanceChanges")) {
|
|
134
|
+
throw new SmokeResponseShapeError(`${toolName}.data.requestedAccountTransactionFacts[${factIndex}].transactionContext must not include transaction-wide balanceChanges`);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
return {
|
|
138
|
+
requestedAccountTransactionFactCount: facts.length,
|
|
139
|
+
requestedAccountTransactionFactBalanceChangeRowCount: balanceChangeRows
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function summarizeCompactResponseSupport(transactions, toolName) {
|
|
143
|
+
let fullDetailsReturned = false;
|
|
144
|
+
let compactReturned = false;
|
|
145
|
+
let compactBalanceChangeRowCount = 0;
|
|
146
|
+
let compactAggregatedBalanceChangeRowCount = 0;
|
|
147
|
+
let transactionContextCount = 0;
|
|
148
|
+
let requestedAccountEffectBalanceChangeRowCount = 0;
|
|
149
|
+
let requestedAccountEffectTruncatedTransactionCount = 0;
|
|
150
|
+
transactions.forEach((transactionValue, transactionIndex) => {
|
|
151
|
+
const transaction = requiredObject(transactionValue, `${toolName}.data.transactions[${transactionIndex}]`);
|
|
152
|
+
if (Object.hasOwn(transaction, "details")) {
|
|
153
|
+
fullDetailsReturned = true;
|
|
154
|
+
}
|
|
155
|
+
const transactionContext = objectValue(transaction.transactionContext);
|
|
156
|
+
if (transactionContext !== undefined) {
|
|
157
|
+
transactionContextCount += 1;
|
|
158
|
+
if (transactionContext.factScope !== "transaction") {
|
|
159
|
+
throw new Error(`${toolName}.data.transactions[${transactionIndex}].transactionContext.factScope must be "transaction"`);
|
|
160
|
+
}
|
|
161
|
+
if (transactionContext.requestedAccountScoped !== false) {
|
|
162
|
+
throw new Error(`${toolName}.data.transactions[${transactionIndex}].transactionContext.requestedAccountScoped must be false`);
|
|
163
|
+
}
|
|
164
|
+
if (Object.hasOwn(transactionContext, "balanceChanges")) {
|
|
165
|
+
throw new SmokeResponseShapeError(`${toolName}.data.transactions[${transactionIndex}].transactionContext must not include transaction-wide balanceChanges`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const requestedAccountEffect = objectValue(transaction.requestedAccountEffect);
|
|
169
|
+
if (requestedAccountEffect !== undefined) {
|
|
170
|
+
requiredLiteral(requestedAccountEffect.scope, "requested_account", `${toolName}.data.transactions[${transactionIndex}].requestedAccountEffect.scope`);
|
|
171
|
+
const completeness = requiredBalanceChangeCompleteness(requestedAccountEffect.balanceChangeCompleteness, `${toolName}.data.transactions[${transactionIndex}].requestedAccountEffect.balanceChangeCompleteness`);
|
|
172
|
+
if (completeness === "truncated") {
|
|
173
|
+
requestedAccountEffectTruncatedTransactionCount += 1;
|
|
174
|
+
}
|
|
175
|
+
requestedAccountEffectBalanceChangeRowCount += requiredArray(requestedAccountEffect.balanceChanges, `${toolName}.data.transactions[${transactionIndex}].requestedAccountEffect.balanceChanges`).length;
|
|
176
|
+
}
|
|
177
|
+
const compact = objectValue(transaction.compact);
|
|
178
|
+
if (compact === undefined) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
compactReturned = true;
|
|
182
|
+
if (compact.factScope !== "transaction") {
|
|
183
|
+
throw new Error(`${toolName}.data.transactions[${transactionIndex}].compact.factScope must be "transaction"`);
|
|
184
|
+
}
|
|
185
|
+
if (compact.requestedAccountScoped !== false) {
|
|
186
|
+
throw new Error(`${toolName}.data.transactions[${transactionIndex}].compact.requestedAccountScoped must be false`);
|
|
187
|
+
}
|
|
188
|
+
const balanceChanges = requiredArray(compact.balanceChanges, `${toolName}.data.transactions[${transactionIndex}].compact.balanceChanges`);
|
|
189
|
+
compactBalanceChangeRowCount += balanceChanges.length;
|
|
190
|
+
balanceChanges.forEach((changeValue, changeIndex) => {
|
|
191
|
+
const change = requiredObject(changeValue, `${toolName}.data.transactions[${transactionIndex}].compact.balanceChanges[${changeIndex}]`);
|
|
192
|
+
if (change.count === undefined) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const count = requiredPositiveInteger(change.count, `${toolName}.data.transactions[${transactionIndex}].compact.balanceChanges[${changeIndex}].count`);
|
|
196
|
+
if (count > 1) {
|
|
197
|
+
compactAggregatedBalanceChangeRowCount += 1;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
return {
|
|
202
|
+
fullDetailsReturned,
|
|
203
|
+
compactReturned,
|
|
204
|
+
compactBalanceChangeRowCount,
|
|
205
|
+
compactAggregatedBalanceChangeRowCount,
|
|
206
|
+
transactionContextCount,
|
|
207
|
+
requestedAccountEffectBalanceChangeRowCount,
|
|
208
|
+
requestedAccountEffectTruncatedTransactionCount
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function requiredObject(value, path) {
|
|
212
|
+
const object = objectValue(value);
|
|
213
|
+
if (object === undefined) {
|
|
214
|
+
throw new SmokeResponseShapeError(`${path} must be an object`);
|
|
215
|
+
}
|
|
216
|
+
return object;
|
|
217
|
+
}
|
|
218
|
+
function objectValue(value) {
|
|
219
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
220
|
+
? value
|
|
221
|
+
: undefined;
|
|
222
|
+
}
|
|
223
|
+
function requiredArray(value, path) {
|
|
224
|
+
if (!Array.isArray(value)) {
|
|
225
|
+
throw new SmokeResponseShapeError(`${path} must be an array`);
|
|
226
|
+
}
|
|
227
|
+
return value;
|
|
228
|
+
}
|
|
229
|
+
function requiredString(value, path) {
|
|
230
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
231
|
+
throw new SmokeResponseShapeError(`${path} must be a non-empty string`);
|
|
232
|
+
}
|
|
233
|
+
return value;
|
|
234
|
+
}
|
|
235
|
+
function requiredBoolean(value, path) {
|
|
236
|
+
if (typeof value !== "boolean") {
|
|
237
|
+
throw new SmokeResponseShapeError(`${path} must be a boolean`);
|
|
238
|
+
}
|
|
239
|
+
return value;
|
|
240
|
+
}
|
|
241
|
+
function requiredBooleanOrNull(value, path) {
|
|
242
|
+
if (typeof value !== "boolean" && value !== null) {
|
|
243
|
+
throw new SmokeResponseShapeError(`${path} must be a boolean or null`);
|
|
244
|
+
}
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
function requiredNonnegativeInteger(value, path) {
|
|
248
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
249
|
+
throw new SmokeResponseShapeError(`${path} must be a nonnegative integer`);
|
|
250
|
+
}
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
253
|
+
function requiredPositiveInteger(value, path) {
|
|
254
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1) {
|
|
255
|
+
throw new SmokeResponseShapeError(`${path} must be a positive integer`);
|
|
256
|
+
}
|
|
257
|
+
return value;
|
|
258
|
+
}
|
|
259
|
+
function requiredAccountSource(value, path) {
|
|
260
|
+
if (value === "active_account_context" || value === "explicit_filter") {
|
|
261
|
+
return value;
|
|
262
|
+
}
|
|
263
|
+
throw new SmokeResponseShapeError(`${path} must be active_account_context or explicit_filter`);
|
|
264
|
+
}
|
|
265
|
+
function requiredRelationship(value, path) {
|
|
266
|
+
if (value === "affected" || value === "sent") {
|
|
267
|
+
return value;
|
|
268
|
+
}
|
|
269
|
+
throw new SmokeResponseShapeError(`${path} must be affected or sent`);
|
|
270
|
+
}
|
|
271
|
+
function requiredBalanceChangeCompleteness(value, path) {
|
|
272
|
+
if (value === "complete" || value === "truncated" || value === "unavailable") {
|
|
273
|
+
return value;
|
|
274
|
+
}
|
|
275
|
+
throw new SmokeResponseShapeError(`${path} must be complete, truncated, or unavailable`);
|
|
276
|
+
}
|
|
277
|
+
function requiredAccountBalanceChangeEvidence(value, path) {
|
|
278
|
+
if (value === "account_balance_changes_returned" ||
|
|
279
|
+
value === "no_account_balance_changes_returned" ||
|
|
280
|
+
value === "incomplete_account_balance_changes" ||
|
|
281
|
+
value === "account_balance_changes_unavailable") {
|
|
282
|
+
return value;
|
|
283
|
+
}
|
|
284
|
+
throw new SmokeResponseShapeError(`${path} must be a valid account balance-change evidence marker`);
|
|
285
|
+
}
|
|
286
|
+
function requiredAccountBalanceChangeInferencePolicy(value, path) {
|
|
287
|
+
if (value === "use_returned_account_balance_changes" ||
|
|
288
|
+
value === "account_absence_proven_by_complete_details" ||
|
|
289
|
+
value === "do_not_infer_from_transaction_context") {
|
|
290
|
+
return value;
|
|
291
|
+
}
|
|
292
|
+
throw new SmokeResponseShapeError(`${path} must be a valid account balance-change inference policy`);
|
|
293
|
+
}
|
|
294
|
+
function expectedAccountBalanceChangeInferencePolicy(evidence, absenceProven) {
|
|
295
|
+
if (evidence === "account_balance_changes_returned") {
|
|
296
|
+
return "use_returned_account_balance_changes";
|
|
297
|
+
}
|
|
298
|
+
if (evidence === "no_account_balance_changes_returned" && absenceProven) {
|
|
299
|
+
return "account_absence_proven_by_complete_details";
|
|
300
|
+
}
|
|
301
|
+
return "do_not_infer_from_transaction_context";
|
|
302
|
+
}
|
|
303
|
+
function requiredLiteral(value, expected, path) {
|
|
304
|
+
if (value === expected) {
|
|
305
|
+
return expected;
|
|
306
|
+
}
|
|
307
|
+
throw new SmokeResponseShapeError(`${path} must be ${expected}`);
|
|
308
|
+
}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mainnetCoins } from "@mysten/deepbook-v3";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { SqliteActivityStore } from "../core/activity/sqliteActivityStore.js";
|
|
5
|
+
import { createDeepbookSwapTransactionMaterialDigestProducer, createDeepbookSwapTransactionMaterialProducer } from "../adapters/deepbook/deepbookTransactionMaterialProducer.js";
|
|
6
|
+
import { createDeepbookSwapHumanReadableReviewProducer } from "../adapters/deepbook/deepbookHumanReviewProducer.js";
|
|
7
|
+
import { createFlowxSwapTransactionMaterialDigestProducer, createFlowxSwapTransactionMaterialProducer } from "../adapters/flowx/flowxSwapTransactionMaterialProducer.js";
|
|
8
|
+
import { createFlowxSwapHumanReadableReviewProducer } from "../adapters/flowx/flowxSwapHumanReviewProducer.js";
|
|
9
|
+
import { createFlowxSwapReviewQuoteSource } from "../core/read/flowxQuoteClient.js";
|
|
10
|
+
import { validateSupportedAdapterLifecycle } from "../adapters/adapterLifecycleValidators.js";
|
|
11
|
+
import { buildSupportedReviewAdapters } from "../adapters/reviewAdapters.js";
|
|
12
|
+
import { ADAPTER_PROMPT_SURFACES } from "../adapters/adapterPromptSurfaces.js";
|
|
13
|
+
import { TransactionActivityService } from "../core/activity/transactionActivityService.js";
|
|
14
|
+
import { createSuiReadService } from "../core/read/readService.js";
|
|
15
|
+
import { createTransactionObjectOwnershipProducer } from "../core/action/transactionObjectOwnershipProducer.js";
|
|
16
|
+
import { createReviewTimeSimulationProducer } from "../core/action/reviewTimeSimulationEvidence.js";
|
|
17
|
+
import { producePtbVisualizationArtifact } from "../core/action/ptbVisualizationProducer.js";
|
|
18
|
+
import { InMemoryLocalTransactionMaterialStore } from "../core/session/transactionMaterialStore.js";
|
|
19
|
+
import { InMemorySessionStore } from "../core/session/sessionStore.js";
|
|
20
|
+
import { createMcpServer, startMcp } from "../mcp/server.js";
|
|
21
|
+
import { SERVER_NAME, SERVER_NETWORK, SERVER_VERSION } from "../mcp/serverInfo.js";
|
|
22
|
+
import { createReviewHttpServer } from "../review-server/server.js";
|
|
23
|
+
import { DEFAULT_SUI_GRAPHQL_URL, DEFAULT_SUI_GRPC_URL, composeRuntimeConfig, loadBootConfig } from "./config.js";
|
|
24
|
+
import { probeReviewServerIdentity, startReviewServerWithTakeover, terminateProcessByPid } from "./reviewServerAcquire.js";
|
|
25
|
+
import { RuntimeLocalSettingsService } from "./localSettingsService.js";
|
|
26
|
+
import { createStderrLogger } from "./logger.js";
|
|
27
|
+
import { SuiEndpointError, verifyMainnetGraphqlEndpoint, verifyMainnetGrpcEndpoint } from "./suiEndpoint.js";
|
|
28
|
+
import { GraphqlSuiTransactionActivitySource } from "./suiTransactionGraphqlSource.js";
|
|
29
|
+
async function main() {
|
|
30
|
+
const logger = createStderrLogger("runtime");
|
|
31
|
+
let activityStore;
|
|
32
|
+
let reviewServerForCleanup;
|
|
33
|
+
let mcp;
|
|
34
|
+
try {
|
|
35
|
+
const bootConfig = loadBootConfig();
|
|
36
|
+
const store = new SqliteActivityStore({
|
|
37
|
+
databasePath: bootConfig.activityDatabasePath,
|
|
38
|
+
validateAdapterLifecycle: validateSupportedAdapterLifecycle
|
|
39
|
+
});
|
|
40
|
+
activityStore = store;
|
|
41
|
+
const preferencesRepository = store.createPreferencesRepository();
|
|
42
|
+
await preferencesRepository.ensureDefaultLocalSettings({
|
|
43
|
+
suiGrpcUrl: DEFAULT_SUI_GRPC_URL,
|
|
44
|
+
suiGraphqlUrl: DEFAULT_SUI_GRAPHQL_URL
|
|
45
|
+
});
|
|
46
|
+
const storedSuiGrpcUrl = await preferencesRepository.getSuiGrpcUrl();
|
|
47
|
+
const storedSuiGraphqlUrl = await preferencesRepository.getSuiGraphqlUrl();
|
|
48
|
+
const config = composeRuntimeConfig({
|
|
49
|
+
bootConfig,
|
|
50
|
+
env: process.env,
|
|
51
|
+
storedSuiGrpcUrl: storedSuiGrpcUrl?.value,
|
|
52
|
+
storedSuiGraphqlUrl: storedSuiGraphqlUrl?.value,
|
|
53
|
+
defaultSuiGrpcUrl: DEFAULT_SUI_GRPC_URL,
|
|
54
|
+
defaultSuiGraphqlUrl: DEFAULT_SUI_GRAPHQL_URL
|
|
55
|
+
});
|
|
56
|
+
const { client: suiClient, chainIdentifier } = await verifyMainnetGrpcEndpoint({
|
|
57
|
+
url: config.grpcUrl,
|
|
58
|
+
expectedChainIdentifier: config.expectedChainIdentifier
|
|
59
|
+
});
|
|
60
|
+
const localSettings = new RuntimeLocalSettingsService({
|
|
61
|
+
preferencesRepository,
|
|
62
|
+
env: process.env,
|
|
63
|
+
defaultSuiGrpcUrl: DEFAULT_SUI_GRPC_URL,
|
|
64
|
+
defaultSuiGraphqlUrl: DEFAULT_SUI_GRAPHQL_URL,
|
|
65
|
+
bootSuiGrpcUrl: config.suiGrpcUrl,
|
|
66
|
+
bootSuiGraphqlUrl: config.suiGraphqlUrl
|
|
67
|
+
});
|
|
68
|
+
const localData = store.createLocalDataService({
|
|
69
|
+
suiGrpcUrl: DEFAULT_SUI_GRPC_URL,
|
|
70
|
+
suiGraphqlUrl: DEFAULT_SUI_GRAPHQL_URL,
|
|
71
|
+
verifySuiGrpcUrl: async (url) => {
|
|
72
|
+
await verifyMainnetGrpcEndpoint({
|
|
73
|
+
url,
|
|
74
|
+
expectedChainIdentifier: config.expectedChainIdentifier
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
verifySuiGraphqlUrl: async (url) => {
|
|
78
|
+
await verifyMainnetGraphqlEndpoint({
|
|
79
|
+
url,
|
|
80
|
+
expectedChainIdentifier: config.expectedChainIdentifier
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
const transactionMaterialStore = new InMemoryLocalTransactionMaterialStore();
|
|
85
|
+
const sessions = new InMemorySessionStore({
|
|
86
|
+
activityStore: store,
|
|
87
|
+
transactionMaterialStore,
|
|
88
|
+
logger,
|
|
89
|
+
validateAdapterLifecycle: validateSupportedAdapterLifecycle
|
|
90
|
+
});
|
|
91
|
+
const readService = createSuiReadService({
|
|
92
|
+
client: suiClient,
|
|
93
|
+
network: config.network,
|
|
94
|
+
chainIdentifier,
|
|
95
|
+
coinMetadataCache: store.createCoinMetadataCache()
|
|
96
|
+
});
|
|
97
|
+
const reviewServerFactory = createReviewHttpServer({
|
|
98
|
+
host: config.reviewHost,
|
|
99
|
+
store: sessions,
|
|
100
|
+
logger,
|
|
101
|
+
activityStore: store,
|
|
102
|
+
localSettings,
|
|
103
|
+
localData,
|
|
104
|
+
reviewComputationDeps: {
|
|
105
|
+
validateAdapterLifecycle: validateSupportedAdapterLifecycle,
|
|
106
|
+
adapters: buildSupportedReviewAdapters((() => {
|
|
107
|
+
const transactionObjectOwnershipProducer = createTransactionObjectOwnershipProducer({
|
|
108
|
+
materialStore: transactionMaterialStore,
|
|
109
|
+
objectSource: suiClient,
|
|
110
|
+
network: config.network,
|
|
111
|
+
chainIdentifier,
|
|
112
|
+
expectedChainIdentifier: config.expectedChainIdentifier
|
|
113
|
+
});
|
|
114
|
+
const reviewTimeSimulationProducer = createReviewTimeSimulationProducer({
|
|
115
|
+
client: suiClient,
|
|
116
|
+
materialStore: transactionMaterialStore,
|
|
117
|
+
network: config.network,
|
|
118
|
+
chainIdentifier,
|
|
119
|
+
expectedChainIdentifier: config.expectedChainIdentifier
|
|
120
|
+
});
|
|
121
|
+
return {
|
|
122
|
+
deepbook: {
|
|
123
|
+
deepbookQuoteSource: readService,
|
|
124
|
+
deepbookDeepBalanceSource: async (account) => {
|
|
125
|
+
const balance = await suiClient.core.getBalance({
|
|
126
|
+
owner: account,
|
|
127
|
+
coinType: mainnetCoins.DEEP.type
|
|
128
|
+
});
|
|
129
|
+
return balance.balance.balance.toString();
|
|
130
|
+
},
|
|
131
|
+
deepbookTransactionMaterialProducer: createDeepbookSwapTransactionMaterialProducer({
|
|
132
|
+
client: suiClient,
|
|
133
|
+
network: config.network,
|
|
134
|
+
chainIdentifier,
|
|
135
|
+
expectedChainIdentifier: config.expectedChainIdentifier,
|
|
136
|
+
materialStore: transactionMaterialStore
|
|
137
|
+
}),
|
|
138
|
+
deepbookTransactionMaterialDigestProducer: createDeepbookSwapTransactionMaterialDigestProducer({
|
|
139
|
+
materialStore: transactionMaterialStore
|
|
140
|
+
}),
|
|
141
|
+
transactionObjectOwnershipProducer,
|
|
142
|
+
deepbookHumanReadableReviewProducer: createDeepbookSwapHumanReadableReviewProducer(),
|
|
143
|
+
reviewTimeSimulationProducer,
|
|
144
|
+
ptbVisualizationProducer: (vizInput) => producePtbVisualizationArtifact({ materialStore: transactionMaterialStore, ...vizInput })
|
|
145
|
+
},
|
|
146
|
+
flowx: {
|
|
147
|
+
flowxQuoteSource: createFlowxSwapReviewQuoteSource(),
|
|
148
|
+
flowxTransactionMaterialProducer: createFlowxSwapTransactionMaterialProducer({
|
|
149
|
+
client: suiClient,
|
|
150
|
+
network: config.network,
|
|
151
|
+
chainIdentifier,
|
|
152
|
+
expectedChainIdentifier: config.expectedChainIdentifier,
|
|
153
|
+
materialStore: transactionMaterialStore
|
|
154
|
+
}),
|
|
155
|
+
flowxTransactionMaterialDigestProducer: createFlowxSwapTransactionMaterialDigestProducer({
|
|
156
|
+
materialStore: transactionMaterialStore
|
|
157
|
+
}),
|
|
158
|
+
transactionObjectOwnershipProducer,
|
|
159
|
+
flowxHumanReadableReviewProducer: createFlowxSwapHumanReadableReviewProducer(),
|
|
160
|
+
reviewTimeSimulationProducer,
|
|
161
|
+
ptbVisualizationProducer: (vizInput) => producePtbVisualizationArtifact({ materialStore: transactionMaterialStore, ...vizInput })
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
})())
|
|
165
|
+
},
|
|
166
|
+
serverInfo: {
|
|
167
|
+
name: SERVER_NAME,
|
|
168
|
+
version: SERVER_VERSION,
|
|
169
|
+
network: SERVER_NETWORK
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
// The review origin is a single-port singleton: the newest instance takes
|
|
173
|
+
// the fixed port over from a previous instance of our own review server so
|
|
174
|
+
// the most recently started client owns the one wallet-autoconnect origin.
|
|
175
|
+
const reviewServer = await startReviewServerWithTakeover((port) => reviewServerFactory.start(port), config.reviewPort, {
|
|
176
|
+
probeIdentity: (probePort) => probeReviewServerIdentity(probePort, config.reviewHost),
|
|
177
|
+
terminate: terminateProcessByPid,
|
|
178
|
+
delay: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
179
|
+
currentPid: process.pid,
|
|
180
|
+
serviceName: SERVER_NAME,
|
|
181
|
+
logger
|
|
182
|
+
});
|
|
183
|
+
reviewServerForCleanup = reviewServer;
|
|
184
|
+
logger.info("review server started", {
|
|
185
|
+
host: reviewServer.host,
|
|
186
|
+
port: reviewServer.port
|
|
187
|
+
});
|
|
188
|
+
let shuttingDown = false;
|
|
189
|
+
const shutdown = async (signal) => {
|
|
190
|
+
logger.info("shutdown requested", { signal });
|
|
191
|
+
try {
|
|
192
|
+
const closeResults = await Promise.allSettled([
|
|
193
|
+
...(mcp ? [mcp.close()] : []),
|
|
194
|
+
reviewServer.close()
|
|
195
|
+
]);
|
|
196
|
+
for (const result of closeResults) {
|
|
197
|
+
if (result.status === "rejected") {
|
|
198
|
+
logger.error("shutdown close failed", {
|
|
199
|
+
error: result.reason instanceof Error ? result.reason.message : String(result.reason)
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
logger.error("shutdown failed", {
|
|
206
|
+
error: error instanceof Error ? error.message : String(error)
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
try {
|
|
211
|
+
store.close();
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
logger.error("activity store close failed", {
|
|
215
|
+
error: error instanceof Error ? error.message : String(error)
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
process.exit(exitCodeForSignal(signal));
|
|
220
|
+
};
|
|
221
|
+
const handleSignal = (signal) => {
|
|
222
|
+
if (shuttingDown) {
|
|
223
|
+
process.exit(exitCodeForSignal(signal));
|
|
224
|
+
}
|
|
225
|
+
shuttingDown = true;
|
|
226
|
+
void shutdown(signal).catch((error) => {
|
|
227
|
+
logger.error("shutdown failed", {
|
|
228
|
+
error: error instanceof Error ? error.message : String(error)
|
|
229
|
+
});
|
|
230
|
+
process.exit(exitCodeForSignal(signal));
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
process.on("SIGINT", () => handleSignal("SIGINT"));
|
|
234
|
+
process.on("SIGTERM", () => handleSignal("SIGTERM"));
|
|
235
|
+
mcp = createMcpServer({
|
|
236
|
+
promptSurfaces: ADAPTER_PROMPT_SURFACES,
|
|
237
|
+
sessions,
|
|
238
|
+
activityStore: store,
|
|
239
|
+
reviewBaseUrl: `http://${reviewServer.host}:${reviewServer.port}`,
|
|
240
|
+
readService,
|
|
241
|
+
transactionActivityService: new TransactionActivityService({
|
|
242
|
+
activityStore: store,
|
|
243
|
+
source: new GraphqlSuiTransactionActivitySource({
|
|
244
|
+
url: config.graphqlUrl,
|
|
245
|
+
expectedChainIdentifier: config.expectedChainIdentifier
|
|
246
|
+
})
|
|
247
|
+
}),
|
|
248
|
+
localSettings,
|
|
249
|
+
logger
|
|
250
|
+
});
|
|
251
|
+
await startMcp(mcp, new StdioServerTransport());
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
const closeResults = await Promise.allSettled([
|
|
255
|
+
...(mcp ? [mcp.close()] : []),
|
|
256
|
+
...(reviewServerForCleanup ? [reviewServerForCleanup.close()] : [])
|
|
257
|
+
]);
|
|
258
|
+
for (const result of closeResults) {
|
|
259
|
+
if (result.status === "rejected") {
|
|
260
|
+
logger.error("startup cleanup close failed", {
|
|
261
|
+
error: result.reason instanceof Error ? result.reason.message : String(result.reason)
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
activityStore?.close();
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
logger.error("activity store close failed", {
|
|
270
|
+
error: error instanceof Error ? error.message : String(error)
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
main().catch((error) => {
|
|
277
|
+
const logger = createStderrLogger("runtime");
|
|
278
|
+
logger.error("fatal runtime error", fatalErrorMeta(error));
|
|
279
|
+
process.exit(1);
|
|
280
|
+
});
|
|
281
|
+
function exitCodeForSignal(signal) {
|
|
282
|
+
return signal === "SIGINT" ? 130 : 143;
|
|
283
|
+
}
|
|
284
|
+
function fatalErrorMeta(error) {
|
|
285
|
+
if (error instanceof SuiEndpointError) {
|
|
286
|
+
return {
|
|
287
|
+
error: error.message,
|
|
288
|
+
kind: error.kind,
|
|
289
|
+
details: error.details
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
error: error instanceof Error ? error.message : String(error)
|
|
294
|
+
};
|
|
295
|
+
}
|