@zktx.io/sui-mcp 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/LICENSES/@mysten-bcs-2.0.5-Apache-2.0.txt +205 -0
- package/LICENSES/@mysten-sui-2.17.0-Apache-2.0.txt +201 -0
- package/LICENSES/@mysten-utils-0.3.3-Apache-2.0.txt +205 -0
- package/LICENSES/fancy-canvas-2.1.0-MIT.txt +7 -0
- package/LICENSES/lightweight-charts-5.2.0-NOTICE.txt +2 -0
- package/README.md +288 -0
- package/dist/adapters/adapterLifecycleValidators.js +5 -0
- package/dist/adapters/adapterPromptSurfaces.js +60 -0
- package/dist/adapters/deepbook/deepbookHumanReviewProducer.js +178 -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 +254 -0
- package/dist/adapters/intentPlanFactories.js +51 -0
- package/dist/adapters/reviewAdapters.js +47 -0
- package/dist/core/action/adapterLifecycleValidation.js +12 -0
- package/dist/core/action/contractNameRegistry.js +151 -0
- package/dist/core/action/forbiddenFields.js +43 -0
- package/dist/core/action/humanReadableReviewEvidence.js +193 -0
- package/dist/core/action/humanReadableReviewProjectionVerifier.js +29 -0
- package/dist/core/action/ptbVisualizationProducer.js +71 -0
- package/dist/core/action/receiptPtbGraph.js +29 -0
- package/dist/core/action/reviewCheckResults.js +6 -0
- package/dist/core/action/reviewStateValidation.js +11 -0
- package/dist/core/action/reviewTimeSimulationEvidence.js +470 -0
- package/dist/core/action/schemas.js +491 -0
- package/dist/core/action/signableAdapterContract.js +998 -0
- package/dist/core/action/suiChainReceiptEvidence.js +106 -0
- package/dist/core/action/suiChainReceiptMapping.js +107 -0
- package/dist/core/action/suiChainReceiptReader.js +211 -0
- package/dist/core/action/suiChainReceiptVerifier.js +178 -0
- package/dist/core/action/swapHumanReadableReviewProjection.js +130 -0
- package/dist/core/action/swapQuotePolicyEvidence.js +271 -0
- package/dist/core/action/transactionFunding.js +244 -0
- package/dist/core/action/transactionObjectOwnershipEvidence.js +256 -0
- package/dist/core/action/transactionObjectOwnershipProducer.js +323 -0
- package/dist/core/action/types.js +33 -0
- package/dist/core/action/walletReviewContractAssembler.js +286 -0
- package/dist/core/activity/accountAssetTimeline.js +157 -0
- package/dist/core/activity/accountAssetTimelineUsdcReferences.js +120 -0
- package/dist/core/activity/activityStore.js +16 -0
- package/dist/core/activity/externalActivityCoverage.js +76 -0
- package/dist/core/activity/externalActivityTransactionStream.js +82 -0
- package/dist/core/activity/localDataService.js +296 -0
- package/dist/core/activity/localDataTypes.js +11 -0
- package/dist/core/activity/localDataValidation.js +439 -0
- package/dist/core/activity/schemaVersion.js +2 -0
- package/dist/core/activity/sqliteActivityStore.js +1068 -0
- package/dist/core/activity/sqliteActivityStoreRows.js +389 -0
- package/dist/core/activity/sqliteActivityStoreSchema.js +367 -0
- package/dist/core/activity/sqliteActivityStoreTypes.js +5 -0
- package/dist/core/activity/suiFunctionTarget.js +43 -0
- package/dist/core/activity/transactionActivityAccountEffects.js +186 -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 +85 -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/deepbookOfficialIndexerSource.js +373 -0
- package/dist/core/read/deepbookRawQuoteClient.js +86 -0
- package/dist/core/read/deepbookReadHelpers.js +321 -0
- package/dist/core/read/deepbookRegistry.js +157 -0
- package/dist/core/read/deepbookSourceOwners.js +159 -0
- package/dist/core/read/deepbookUsdcChartService.js +342 -0
- package/dist/core/read/intentEvidenceResponseFormatting.js +228 -0
- package/dist/core/read/readCardInputs.js +19 -0
- package/dist/core/read/readCardResult.js +40 -0
- package/dist/core/read/readResponseGuidance.js +402 -0
- package/dist/core/read/readService.js +1639 -0
- package/dist/core/read/readServiceTypes.js +88 -0
- package/dist/core/read/settlementParityFormatting.js +82 -0
- package/dist/core/read/walletReadHelpers.js +99 -0
- package/dist/core/review/reviewChecks.js +45 -0
- package/dist/core/review/reviewComputation.js +38 -0
- package/dist/core/review/reviewComputationResult.js +87 -0
- package/dist/core/session/cardSession.js +31 -0
- package/dist/core/session/cardSessionStore.js +204 -0
- package/dist/core/session/keyedRecordStore.js +18 -0
- package/dist/core/session/liveReviewSessionContract.js +3 -0
- package/dist/core/session/localSession.js +31 -0
- package/dist/core/session/privateReviewArtifacts.js +75 -0
- package/dist/core/session/reviewValidity.js +49 -0
- package/dist/core/session/sessionErrors.js +9 -0
- package/dist/core/session/sessionRecordStore.js +40 -0
- package/dist/core/session/sessionStore.js +655 -0
- package/dist/core/session/settingsSession.js +1 -0
- package/dist/core/session/settingsSessions.js +45 -0
- package/dist/core/session/sqliteCardStore.js +88 -0
- package/dist/core/session/sqliteSessionStore.js +213 -0
- package/dist/core/session/sqliteTransactionMaterialStore.js +64 -0
- package/dist/core/session/sqliteWalletWorkflowStore.js +821 -0
- package/dist/core/session/status.js +60 -0
- package/dist/core/session/transactionMaterialStore.js +221 -0
- package/dist/core/session/transactionRequest.js +72 -0
- package/dist/core/session/wait.js +79 -0
- package/dist/core/session/walletConnection.js +92 -0
- package/dist/core/session/walletRuntime.js +38 -0
- package/dist/core/session/walletWorkflow.js +608 -0
- package/dist/core/session/workflowState.js +80 -0
- package/dist/core/session/workflowView.js +150 -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 +326 -0
- package/dist/mcp/result.js +17 -0
- package/dist/mcp/schemas.js +11 -0
- package/dist/mcp/server.js +32 -0
- package/dist/mcp/serverInfo.js +131 -0
- package/dist/mcp/toolErrors.js +118 -0
- package/dist/mcp/toolNames.js +58 -0
- package/dist/mcp/tools/account/index.js +44 -0
- package/dist/mcp/tools/action/prepareSuiActionReview.js +126 -0
- package/dist/mcp/tools/read/commonSchemas.js +43 -0
- package/dist/mcp/tools/read/deepbookReadTools.js +686 -0
- package/dist/mcp/tools/read/index.js +14 -0
- package/dist/mcp/tools/read/readToolHelpers.js +97 -0
- package/dist/mcp/tools/read/reviewActivityTools.js +179 -0
- package/dist/mcp/tools/read/serverStatusTools.js +100 -0
- package/dist/mcp/tools/read/transactionActivityOutput.js +371 -0
- package/dist/mcp/tools/read/transactionActivityTools.js +858 -0
- package/dist/mcp/tools/read/walletReadTools.js +734 -0
- package/dist/mcp/tools/session/executionResultTools.js +44 -0
- package/dist/mcp/tools/session/index.js +8 -0
- package/dist/mcp/tools/session/shared.js +36 -0
- package/dist/mcp/tools/session/statusTools.js +69 -0
- package/dist/mcp/tools/session/walletConnectionTools.js +69 -0
- package/dist/mcp/tools/settings/index.js +66 -0
- package/dist/mcp-app/account.html +3133 -0
- package/dist/mcp-app/account.notices.txt +973 -0
- package/dist/mcp-app/chart.html +3354 -0
- package/dist/mcp-app/chart.notices.txt +1194 -0
- package/dist/mcp-app/connect.html +3179 -0
- package/dist/mcp-app/connect.notices.txt +1012 -0
- package/dist/mcp-app/receipt.html +8430 -0
- package/dist/mcp-app/receipt.notices.txt +3549 -0
- package/dist/mcp-app/review.html +8430 -0
- package/dist/mcp-app/review.notices.txt +3549 -0
- package/dist/mcp-ui/contracts.js +31 -0
- package/dist/mcp-ui/readCards.js +28 -0
- package/dist/mcp-ui/tools.js +134 -0
- package/dist/review-app/brand-dark.svg +1 -0
- package/dist/review-app/brand-light.svg +1 -0
- package/dist/review-app/favicon.svg +1 -0
- package/dist/review-app/settings.css +1 -0
- package/dist/review-app/settings.js +1 -0
- package/dist/review-app/ui.css +809 -0
- package/dist/review-server/assets.js +48 -0
- package/dist/review-server/html.js +45 -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 +1 -0
- package/dist/review-server/server.js +72 -0
- package/dist/review-server/settingsApi.js +158 -0
- package/dist/runtime/application.js +203 -0
- package/dist/runtime/config.js +97 -0
- package/dist/runtime/localSettingsService.js +198 -0
- package/dist/runtime/logger.js +66 -0
- package/dist/runtime/reviewDependencies.js +58 -0
- package/dist/runtime/reviewServerAcquire.js +93 -0
- package/dist/runtime/runtimeTermination.js +60 -0
- package/dist/runtime/shared/authenticatedFetch.js +127 -0
- package/dist/runtime/shared/control.js +93 -0
- package/dist/runtime/shared/dataAccess.js +66 -0
- package/dist/runtime/shared/mcpHttp.js +84 -0
- package/dist/runtime/shared/ownerLease.js +50 -0
- package/dist/runtime/shared/server.js +98 -0
- package/dist/runtime/shared/stdio.js +113 -0
- package/dist/runtime/smokeMainnetRead.js +391 -0
- package/dist/runtime/smokeMainnetReadAssertions.js +306 -0
- package/dist/runtime/smokeReview.js +40 -0
- package/dist/runtime/start.js +90 -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/dist/runtime/walletConnectConfig.js +3 -0
- package/dist/runtime/walletConnectStorage.js +99 -0
- package/dist/runtime/walletConnectTransport.js +128 -0
- package/dist/runtime/walletSdkChild.js +3 -0
- package/dist/runtime/walletSdkChildRuntime.js +160 -0
- package/dist/runtime/walletSdkIpc.js +26 -0
- package/dist/runtime/walletSdkProcess.js +358 -0
- package/docs/AGENT_BEHAVIOR.md +524 -0
- package/docs/AGENT_DEVELOPMENT_POLICY.md +815 -0
- package/docs/FRONTEND_POLICY.md +534 -0
- package/docs/LOCAL_DB_ARCHITECTURE.md +381 -0
- package/docs/MCP_SETUP.md +742 -0
- package/docs/MCP_TOOLS.md +1318 -0
- package/docs/SDK_API.md +206 -0
- package/docs/SIGNABLE_ADAPTER_CONTRACT.md +396 -0
- package/docs/TRANSACTION_ACTIVITY_LOG.md +194 -0
- package/docs/UTILITY_INDEX.md +275 -0
- package/docs/WALLET_CONNECTION.md +238 -0
- package/docs/golden-scenarios/BEHAVIOR_MATRIX.md +166 -0
- package/docs/golden-scenarios/INTENT_EVIDENCE_GOLDEN_ANSWERS.md +161 -0
- package/docs/golden-scenarios/INTENT_EVIDENCE_MATRIX.md +259 -0
- package/package.json +79 -0
- package/protocols/deepbook-margin.md +15 -0
- package/protocols/deepbook-v3.md +24 -0
package/docs/SDK_API.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# SDK API Verification
|
|
2
|
+
|
|
3
|
+
This document records the pinned SDK APIs used by the current runtime. The source of truth is the installed package source in `node_modules`, not memory or external summaries.
|
|
4
|
+
|
|
5
|
+
## Package Versions
|
|
6
|
+
|
|
7
|
+
- `@modelcontextprotocol/ext-apps`: `1.7.5`
|
|
8
|
+
- `@modelcontextprotocol/sdk`: `1.29.0`
|
|
9
|
+
- `@mysten/sui`: `2.17.0`
|
|
10
|
+
- `@mysten/deepbook-v3`: `1.3.6`
|
|
11
|
+
- `@walletconnect/sign-client`, `@walletconnect/types`, `@walletconnect/utils`: `2.23.10`
|
|
12
|
+
- `qrcode`: `1.5.4`
|
|
13
|
+
- `@zktx.io/ptb-model`: `0.5.0`
|
|
14
|
+
- `mermaid`: `11.12.0`
|
|
15
|
+
|
|
16
|
+
## MCP Apps
|
|
17
|
+
|
|
18
|
+
`@modelcontextprotocol/ext-apps` is pinned to `1.7.5`, with MCP SDK `1.29.0`. The server uses `registerAppTool`, `registerAppResource` and `getUiCapability`; the view uses `App` for host-mediated calls and teardown. Account, Receipt, Chart, Connect and Review are separate self-contained resources, so an account card does not load the PTB or chart renderer. The server keeps app-only permissions out of model content.
|
|
19
|
+
|
|
20
|
+
The shared server uses the pinned MCP SDK Streamable HTTP transport behind authenticated loopback access. Stdio clients forward tool, resource and prompt requests with their original client identity and capabilities. Ordinary MCP input schemas remain unchanged by the transport; the 64 KiB card/HTTP input limit includes the card call envelope.
|
|
21
|
+
|
|
22
|
+
## WalletConnect Runtime
|
|
23
|
+
|
|
24
|
+
The backend passes the product identifier from `src/runtime/walletConnectConfig.ts`
|
|
25
|
+
to the pinned `SignClient.init`. The shared runtime's configuration identity uses
|
|
26
|
+
the same value. There is no user project ID setting or environment override.
|
|
27
|
+
Identifier-format validation remains before SDK initialization. Initialization,
|
|
28
|
+
restoration and runtime-state failures remain separate from wallet approval and
|
|
29
|
+
transaction results; public diagnostics do not include raw SDK error bodies.
|
|
30
|
+
|
|
31
|
+
## Sui gRPC Client
|
|
32
|
+
|
|
33
|
+
Verified from `node_modules/@mysten/sui/src/grpc/index.ts`, `client.ts`, `core.ts`, and `node_modules/@mysten/sui/src/client/types.ts`.
|
|
34
|
+
|
|
35
|
+
- Import path: `@mysten/sui/grpc`
|
|
36
|
+
- Client: `SuiGrpcClient`
|
|
37
|
+
- Constructor input includes:
|
|
38
|
+
- `network`
|
|
39
|
+
- `baseUrl`
|
|
40
|
+
- optional `fetchInit`
|
|
41
|
+
- or custom `transport`
|
|
42
|
+
- Runtime construction:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
new SuiGrpcClient({
|
|
46
|
+
baseUrl: "https://fullnode.mainnet.sui.io:443",
|
|
47
|
+
network: "mainnet"
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Confirmed methods:
|
|
52
|
+
|
|
53
|
+
| Method | Signature Source | Notes |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| `client.core.getChainIdentifier()` | `GrpcCoreClient.getChainIdentifier(_options?)` | Returns `{ chainIdentifier: string }`. |
|
|
56
|
+
| `client.core.listBalances(options)` | `GrpcCoreClient.listBalances(options)` | `options.owner` is required; `options.cursor` and `options.limit` are available. Returns `{ balances, hasNextPage, cursor }`. |
|
|
57
|
+
| `client.core.getCoinMetadata(options)` | `GrpcCoreClient.getCoinMetadata(options)` | `options.coinType` is required. Returns `{ coinMetadata }`; metadata can be `null`. The gRPC implementation resolves type through MVR before calling `stateService.getCoinInfo`; the pinned gRPC implementation catches `getCoinInfo` failures and returns `coinMetadata: null`, so callers cannot distinguish those failures from missing metadata through this method alone. |
|
|
58
|
+
| `client.core.simulateTransaction(options)` | `GrpcCoreClient.simulateTransaction(options)` | Accepts `transaction`, optional `include`, optional `checksEnabled`. |
|
|
59
|
+
|
|
60
|
+
`SimulateTransactionOptions.checksEnabled` defaults to enabled and can be set to `false` for debug/read inspection. Read-only DeepBook SDK methods use simulation internally and must not be presented as signing readiness.
|
|
61
|
+
|
|
62
|
+
For review-time transaction simulation, use the public gRPC `client.transactionExecutionService.simulateTransaction` with validation checks enabled (`checks: ENABLED`), `doGasSelection: true`, and the complete stored BCS transaction. In the pinned core API, `doGasSelection: false` can let the node inject mock gas for an empty gas payment, changing the simulated digest. Require returned BCS to equal the submitted bytes and require the effects digest to match; selection must not change the reviewed material. Decode transaction facts from the identical returned BCS. Request effects, balance changes and object id/type facts, and require the normalized `effects`, `balanceChanges`, `objectTypes` and `transaction` evidence. Missing required fields must fail closed. Returned BCS is only a private equality check and must not enter public or stored review evidence; raw transaction bytes are not an MCP or review-app output. `commandResults` remains scoped to read-only DeepBook raw quote extraction using `client.core.simulateTransaction`, not swap review simulation evidence. Failed simulations are blocked pre-signing review facts, not wallet rejection, transaction submission failure, or automatic transient retry evidence. A thrown simulation call is refreshable only when it is classified as a transport, RPC, timeout, or endpoint availability failure; malformed transaction material, request-shape bugs, incomplete results, and adapter defects remain blocked.
|
|
63
|
+
|
|
64
|
+
Only an explicit `effects.status.success: false` reports simulation failure. A missing transaction, effects, status, or boolean success value means the response cannot establish an outcome. Incomplete or inconsistent evidence blocks the review with a fixed explanation; internal validation and JavaScript error messages are not public review facts. A `success: true` response still requires all material and evidence checks above.
|
|
65
|
+
|
|
66
|
+
During transaction building, the SDK's `SimulationError.executionError` does
|
|
67
|
+
not preserve every gRPC error kind. A build error can establish a returned
|
|
68
|
+
simulation rejection without establishing a specific funding shortfall. Build
|
|
69
|
+
error text is not used to infer insufficient gas or coin balance. Explicit
|
|
70
|
+
shortfalls remain available from verified funding reads and the typed error
|
|
71
|
+
kinds returned directly by review-time simulation.
|
|
72
|
+
|
|
73
|
+
## DeepBook Read Methods
|
|
74
|
+
|
|
75
|
+
Verified from `node_modules/@mysten/deepbook-v3/src/client.ts` and `node_modules/@mysten/deepbook-v3/src/types/index.ts`.
|
|
76
|
+
|
|
77
|
+
- Import path: `@mysten/deepbook-v3`
|
|
78
|
+
- Client: `DeepBookClient`
|
|
79
|
+
- Constructor requires:
|
|
80
|
+
- `client`
|
|
81
|
+
- `address`
|
|
82
|
+
- `network`
|
|
83
|
+
- Constructor also accepts optional configured `balanceManagers`; Sui MCP uses this only to register a user-supplied `managerAddress` as an ephemeral SDK BalanceManager key for account-bound inventory detail reads.
|
|
84
|
+
|
|
85
|
+
The `address` is used by the SDK as the transaction simulation sender for read queries. For sender-independent DeepBook orderbook, raw-quantity quote, and display-amount quote reads, Sui MCP supplies an internal mainnet placeholder address. This placeholder is not user identity and must not be represented as wallet authorization.
|
|
86
|
+
|
|
87
|
+
Account-bound DeepBook reads, such as `read.summarize_deepbook_account_inventory`, use the active account address as the simulation sender. The product filters manager detail reads through on-chain `getBalanceManagerIds(owner)` discovery before calling account-bound detail methods; this is active read context, not signing authorization or custody.
|
|
88
|
+
|
|
89
|
+
Confirmed methods:
|
|
90
|
+
|
|
91
|
+
| Method | Return Type | Used For |
|
|
92
|
+
| --- | --- | --- |
|
|
93
|
+
| `midPrice(poolKey)` | `Promise<number>` | Orderbook context. |
|
|
94
|
+
| `poolBookParams(poolKey)` | `Promise<PoolBookParams>` | Tick, lot, and min size context. |
|
|
95
|
+
| `getLevel2TicksFromMid(poolKey, ticks)` | `Promise<Level2TicksFromMid>` | Bid/ask levels around mid price. |
|
|
96
|
+
| `deepBook.getQuoteQuantityOut(poolKey, baseQuantity)` | Transaction builder thunk | Base-to-quote quantity quote. Sui MCP passes positive raw input quantities that fit the SDK `u64` argument and parses the simulated raw `u64` return values directly. |
|
|
97
|
+
| `deepBook.getBaseQuantityOut(poolKey, quoteQuantity)` | Transaction builder thunk | Quote-to-base quantity quote. Sui MCP passes positive raw input quantities that fit the SDK `u64` argument and parses the simulated raw `u64` return values directly. |
|
|
98
|
+
| `getBalanceManagerIds(owner)` | `Promise<string[]>` | Active-account BalanceManager discovery. |
|
|
99
|
+
| `accountExists(poolKey, managerKey)` | `Promise<boolean>` | Gate before account-bound detail reads. |
|
|
100
|
+
| `account(poolKey, managerKey)` | `Promise<AccountInfo>` | Display-like account ledger and rebate inventory. Not raw/signable quantity. |
|
|
101
|
+
| `lockedBalance(poolKey, balanceManagerKey)` | `Promise<LockedBalances>` | Display-like balances tied to open orders. Not withdrawable/spendable readiness. |
|
|
102
|
+
| `accountOpenOrders(poolKey, managerKey)` | `Promise<string[]>` | Open order ID inventory; Sui MCP caps returned IDs in its public response. |
|
|
103
|
+
|
|
104
|
+
Relevant return shapes:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
type PoolBookParams = {
|
|
108
|
+
tickSize: number;
|
|
109
|
+
lotSize: number;
|
|
110
|
+
minSize: number;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
type Level2TicksFromMid = {
|
|
114
|
+
bid_prices: number[];
|
|
115
|
+
bid_quantities: number[];
|
|
116
|
+
ask_prices: number[];
|
|
117
|
+
ask_quantities: number[];
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type QuoteQuantityOut = {
|
|
121
|
+
baseQuantity: number;
|
|
122
|
+
baseOut: number;
|
|
123
|
+
quoteOut: number;
|
|
124
|
+
deepRequired: number;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
type BaseQuantityOut = {
|
|
128
|
+
quoteQuantity: number;
|
|
129
|
+
baseOut: number;
|
|
130
|
+
quoteOut: number;
|
|
131
|
+
deepRequired: number;
|
|
132
|
+
};
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The pinned SDK accepts `number | bigint` quote inputs. Its high-level quote query objects include an input echo field (`baseQuantity` or `quoteQuantity`) produced with `Number(inputRaw)`, plus display quote fields (`baseOut`, `quoteOut`, and `deepRequired`) produced after scalar division and `Number(...)` conversion. Sui MCP does not use those high-level query objects as the canonical quote source for adapter preparation. It uses the pinned SDK transaction builder quote functions, requests `client.core.simulateTransaction` command results, and parses raw `u64` return values. The simulated public Move entrypoint is `pool::get_quote_quantity_out` for base-to-quote reads and `pool::get_base_quantity_out` for quote-to-base reads; both delegate to `pool::get_quantity_out`, whose official Move source defines the return order as `base_quantity_out`, `quote_quantity_out`, and `deep_quantity_required`. Public `quote` fields are exact decimal display strings derived from those raw values through pinned DeepBook scalars; `rawQuote` carries the raw evidence. `read.quote_deepbook_action` marks the input as raw `u64`, while `read.quote_deepbook_display_amount` marks the input as a source display amount converted to raw `u64`. Raw quote evidence is not an effective price, price-impact calculation, quote-vs-mid slippage calculation, venue comparison, best-route claim, fiat cash-out estimate, external market lookup, USDC/USD peg assumption, P&L, cost basis, final min-out, signing data, or signing readiness. The account-bound DeepBook review may derive a fresh raw quote policy from this evidence and use that derived policy for local unsigned transaction material build, while keeping bytes private to the backend until a scoped user selection admits a WalletConnect request for that reviewed revision. MCP and ordinary review-status outputs still do not contain transaction bytes, signing data, or signing readiness. When the digest commitment stage completes, it is derived from the locally stored transaction bytes through pinned SDK `Transaction.from(...).getDigest()` and remains an internal binding, not a public signing artifact.
|
|
136
|
+
|
|
137
|
+
## Runtime Boundary
|
|
138
|
+
|
|
139
|
+
- JSON-RPC client imports are not used.
|
|
140
|
+
- Sui gRPC and GraphQL endpoints are resolved from local SQLite settings by default. `SUI_GRPC_URL` and `SUI_GRAPHQL_URL` are advanced temporary overrides and do not mutate stored settings.
|
|
141
|
+
- Sui gRPC URLs must include an explicit port and no credentials, path, query string, or fragment.
|
|
142
|
+
- Sui GraphQL URLs must use `https` and must not include credentials, query string, or fragment.
|
|
143
|
+
- The gRPC endpoint is verified during runtime startup. The GraphQL endpoint is verified when saved, imported, or first used by Sui activity tools.
|
|
144
|
+
- `fetchedAt` fields are ISO 8601 UTC strings produced by `new Date().toISOString()`.
|
|
145
|
+
- Read-only tools may inspect mainnet state but must not create signable transaction material.
|
|
146
|
+
|
|
147
|
+
## WalletConnect and signature verification
|
|
148
|
+
|
|
149
|
+
The SDK child initializes pinned SignClient with its public `storage` injection,
|
|
150
|
+
private session persistence, silent SDK logging and telemetry disabled. It uses
|
|
151
|
+
`connect`, `session.getAll`, `session_update/session_delete/session_expire` events,
|
|
152
|
+
and `request` on chain `sui:mainnet`, method `sui_signTransaction`.
|
|
153
|
+
Pinned `session_event` does not update approved namespaces itself: account/chain
|
|
154
|
+
selection events explicitly invalidate stored review/submission authority even
|
|
155
|
+
when the approved account set stays unchanged. Requests carry
|
|
156
|
+
`{ transaction: <stored BCS base64>, address }`; responses require
|
|
157
|
+
`{ transactionBytes: <BCS base64>, signature }`. No SDK source patch or automatic
|
|
158
|
+
sign-and-execute fallback is used.
|
|
159
|
+
|
|
160
|
+
The backend reconstructs the returned transaction with `Transaction.from`,
|
|
161
|
+
recomputes its digest and calls pinned `verifyTransactionSignature` with the
|
|
162
|
+
admitted address and verified Sui client (including schemes requiring online
|
|
163
|
+
verification). Submission uses `client.core.executeTransaction` exactly once
|
|
164
|
+
per admitted attempt. `waitForTransaction` supplies separately verified chain
|
|
165
|
+
facts; its absence/timeout does not prove execution failure.
|
|
166
|
+
|
|
167
|
+
SDK session storage persists only the pinned connection namespaces. History,
|
|
168
|
+
requests and unknown queue keys are volatile. The SDK has no supported complete
|
|
169
|
+
in-process disposal; its owner process lifetime bounds callbacks and storage.
|
|
170
|
+
The parent uses a fixed packaged Node child entrypoint and private versioned IPC.
|
|
171
|
+
Only the SDK child owns SDK storage. The supervisor fences a terminating run,
|
|
172
|
+
sends SIGKILL to its owned child and waits for actual exit. Its explicit
|
|
173
|
+
replacement primitive remains private infrastructure; Connect and Settings do
|
|
174
|
+
not expose a restart command. Closing relay transport or receiving an IPC disconnection is not
|
|
175
|
+
evidence that the SDK operation ended. No SDK private teardown, source patch,
|
|
176
|
+
automatic financial retry or overlapping storage writer is used.
|
|
177
|
+
|
|
178
|
+
Snapshots and per-session versions distinguish present, absent and unusable
|
|
179
|
+
sessions. Source inspection failure disables the service instead of becoming an
|
|
180
|
+
empty session list. `accountsChanged` and `chainChanged` invalidate selection
|
|
181
|
+
even if namespace values are unchanged. The final pre-submission session check
|
|
182
|
+
runs after asynchronous digest/signature/network checks. Responses from another
|
|
183
|
+
SDK run cannot satisfy that check or restore submission authority.
|
|
184
|
+
Actual target-wallet acceptance of the serialization is an integration
|
|
185
|
+
requirement, not something inferred from these SDK APIs or a rejected request.
|
|
186
|
+
|
|
187
|
+
## Funding formats in Sui 2.17.0
|
|
188
|
+
|
|
189
|
+
The pinned Transaction builder first resolves CoinWithBalance intents. With
|
|
190
|
+
SuiGrpcClient, the SDK's gRPC resolver then asks the node to resolve transaction
|
|
191
|
+
objects, gas payment, and expiration. The common client resolver is a separate
|
|
192
|
+
SDK path; testing it alone does not establish the runtime's gRPC behavior.
|
|
193
|
+
|
|
194
|
+
The source of truth for address-balance withdrawal and gas reservation formats
|
|
195
|
+
is Sui mainnet-v1.72.5 `sui-types/src/coin_reservation.rs` and
|
|
196
|
+
`transaction.rs`, together with the installed Sui 2.17.0 source. Its
|
|
197
|
+
`utils/coin-reservation.ts` helper is not publicly exported. The local read-only
|
|
198
|
+
funding verifier uses the SDK's public BCS, base58 and dynamic-field primitives
|
|
199
|
+
for the documented reservation format; it does not replace SDK coin selection
|
|
200
|
+
or import private package paths. Reservation epochs cover N and N+1.
|
|
201
|
+
|
|
202
|
+
Address-balance gas uses an empty payment array with ValidDuring replay
|
|
203
|
+
protection. A reservation reference can also fund a gas coin together with
|
|
204
|
+
actual coin objects. Source reads and checks-enabled review simulation remain
|
|
205
|
+
required; protocol feature availability alone does not prove wallet acceptance
|
|
206
|
+
or execution success.
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# Signable Adapter and PTB Visualization Contract
|
|
2
|
+
|
|
3
|
+
This document defines the contract boundary for wallet-review adapters.
|
|
4
|
+
It is a product and implementation contract, not a current feature announcement.
|
|
5
|
+
|
|
6
|
+
The backend builds local account-bound DeepBook transaction material and
|
|
7
|
+
binds its Sui digest to verified review evidence. Only explicit user selection
|
|
8
|
+
and wallet approval allow the backend WalletConnect request. Returned bytes and
|
|
9
|
+
signer must match the admission before submission. No model or card receives
|
|
10
|
+
transaction bytes or signatures.
|
|
11
|
+
|
|
12
|
+
The source-level schema for this contract lives in
|
|
13
|
+
`src/core/action/signableAdapterContract.ts`.
|
|
14
|
+
|
|
15
|
+
## Current Status
|
|
16
|
+
|
|
17
|
+
The contract schema is implemented in TypeScript and Zod, and the runtime
|
|
18
|
+
DeepBook account-bound swap reviews emit it. When an account-bound review
|
|
19
|
+
completes every evidence stage (local unsigned transaction material, internal
|
|
20
|
+
digest commitment, object ownership, quote/policy provenance, human-readable
|
|
21
|
+
review facts, and review-time simulation), the review layer assembles those
|
|
22
|
+
private artifacts into a schema-validated `TransactionReviewData` and
|
|
23
|
+
records it on the public review state as `transactionReviewData` on a
|
|
24
|
+
`ready_for_wallet_review` status. If any required evidence is
|
|
25
|
+
missing or fails contract validation, no contract is emitted and the review
|
|
26
|
+
stays blocked with `blockedReason: "wallet_review_contract_emit_missing"`.
|
|
27
|
+
|
|
28
|
+
If that stored failure's private evidence later becomes invalid, current state
|
|
29
|
+
retains the failure reason and stage provenance with `evidenceValidity:
|
|
30
|
+
"invalidated"` and removes the material-derived public summaries. Fresh
|
|
31
|
+
computation still validates every required summary; invalidation does not permit
|
|
32
|
+
a ready contract or wallet admission. Earlier recorded snapshots remain history.
|
|
33
|
+
|
|
34
|
+
`reviewedTransactionDigest` is a hash only. Private bytes travel directly from
|
|
35
|
+
the backend to the wallet through WalletConnect after atomic admission; there
|
|
36
|
+
is no browser handoff endpoint. The adapter contract itself never signs or
|
|
37
|
+
executes. The platform owns request authority and verified chain outcomes.
|
|
38
|
+
|
|
39
|
+
## Final Acceptance Gate
|
|
40
|
+
|
|
41
|
+
This contract defines the data checks required before wallet admission; it does
|
|
42
|
+
not authorize a signature request. The current backend WalletConnect workflow
|
|
43
|
+
requires an explicit permitted Review card action and approval in the wallet.
|
|
44
|
+
The term signable adapter identifies this transaction-review contract, not a
|
|
45
|
+
claim that every displayed proposal is eligible for signing.
|
|
46
|
+
|
|
47
|
+
The gate binds three views of the action to one transaction commitment, so a
|
|
48
|
+
user cannot sign something different from what they reviewed:
|
|
49
|
+
|
|
50
|
+
- The commitment is a digest (hash) of the exact serialized transaction bytes
|
|
51
|
+
that will be signed, represented as the Sui transaction digest. The commitment
|
|
52
|
+
is a hash only; raw transaction bytes remain a prohibited output and must never
|
|
53
|
+
appear in MCP or review responses.
|
|
54
|
+
- `humanReadableReview` must be derived from the transaction identified by that
|
|
55
|
+
commitment.
|
|
56
|
+
- The review-time `simulation` must have been run against the transaction with
|
|
57
|
+
that same commitment.
|
|
58
|
+
- Any bytes handed to the wallet must hash to that same commitment.
|
|
59
|
+
|
|
60
|
+
The acceptance criterion is strict equality: review-commitment equals
|
|
61
|
+
simulation-commitment equals handoff-commitment. If any is missing or differs,
|
|
62
|
+
the contract is invalid and signing stays blocked.
|
|
63
|
+
|
|
64
|
+
### Transaction byte lifecycle (closes the handoff loophole)
|
|
65
|
+
|
|
66
|
+
The signable bytes must have exactly one origin and one handoff path, so an
|
|
67
|
+
adapter cannot display a commitment while signing different bytes through a side
|
|
68
|
+
channel:
|
|
69
|
+
|
|
70
|
+
- Origin: the bytes are produced only inside Sui MCP's review layer (the
|
|
71
|
+
signable adapter), from material Sui MCP independently built or verified.
|
|
72
|
+
They are never accepted from an external MCP or AI-client proposal.
|
|
73
|
+
- Storage: the bytes live only in the local review-server session keyed by
|
|
74
|
+
`reviewSessionId`. They never appear in an MCP tool response or in the
|
|
75
|
+
review-API JSON an AI client reads; those surfaces carry the commitment hash
|
|
76
|
+
only.
|
|
77
|
+
- Transport: the only byte path is the private backend to the wallet through
|
|
78
|
+
its approved WalletConnect session. No browser signer or MCP response carries
|
|
79
|
+
bytes or signatures.
|
|
80
|
+
- Binding: before requesting a signature, recompute the stored bytes' digest
|
|
81
|
+
and require equality with both reviewed producers. Verify the returned bytes'
|
|
82
|
+
digest and selected account's signature again before one backend submission.
|
|
83
|
+
- Admission: one request per review session/revision, consumed atomically with
|
|
84
|
+
the card selection and public history. A different card cannot duplicate the
|
|
85
|
+
request. Recomputing while signature/submission callbacks or initial chain
|
|
86
|
+
observation remain unsettled is refused. Local timeout or stop does not prove
|
|
87
|
+
remote cancellation or callback cleanup.
|
|
88
|
+
- Results: request status and chain success/failure are separate. Unknown
|
|
89
|
+
outcomes retain the known digest and may be read again, never resubmitted.
|
|
90
|
+
A later explicit reviewed revision has a new attempt while prior facts remain.
|
|
91
|
+
|
|
92
|
+
DeepBook swap material is built with an explicit fee mode. When the account's
|
|
93
|
+
DEEP balance covers the protocol fee, the swap quotes and builds in DEEP fee
|
|
94
|
+
mode; otherwise it re-quotes through the protocol's input-fee dry run and
|
|
95
|
+
builds with an explicit zero-DEEP coin so the taker fee is paid from the
|
|
96
|
+
source coin at the protocol penalty. The selected fee mode is recorded as
|
|
97
|
+
review evidence and shown as a check. Before building, the producer verifies
|
|
98
|
+
the account holds the source amount plus the explicit gas budget and fails
|
|
99
|
+
closed with the exact required and held amounts.
|
|
100
|
+
|
|
101
|
+
This gate is enforced at the contract-schema layer. `transactionReviewDataSchema`
|
|
102
|
+
requires a `reviewedTransactionDigest` (the Sui transaction digest of the
|
|
103
|
+
transaction that will be signed, validated with the pinned SDK source of truth
|
|
104
|
+
`isValidTransactionDigest`; a digest only, never raw bytes) and binds
|
|
105
|
+
`humanReadableReview.transactionDigest` and `simulation.transactionDigest` to it
|
|
106
|
+
through a `superRefine` invariant (reusing the `requireEqual` cross-field helper)
|
|
107
|
+
that rejects any contract whose three commitments are missing, malformed, or
|
|
108
|
+
unequal (`src/core/action/signableAdapterContract.ts`,
|
|
109
|
+
`test/signableAdapterContract.test.ts`).
|
|
110
|
+
|
|
111
|
+
The private `prepareReviewedTransaction` session-store operation verifies stored
|
|
112
|
+
material and the reviewed digest. `WalletWorkflow` and its SQLite owner admit
|
|
113
|
+
the exact account/revision, verify wallet response bytes and signature, submit
|
|
114
|
+
once and record independently read receipt facts. Public output never gains
|
|
115
|
+
signing authority. Internal preparation is distinct from final user admission.
|
|
116
|
+
|
|
117
|
+
## Adapter Contract
|
|
118
|
+
|
|
119
|
+
A wallet-review adapter that returns this contract must regenerate or
|
|
120
|
+
independently verify action material inside Sui MCP before any wallet
|
|
121
|
+
handoff exists. External MCP or AI-client proposals remain untrusted structured
|
|
122
|
+
input and cannot become transaction-building authority.
|
|
123
|
+
|
|
124
|
+
The adapter contract requires these fields:
|
|
125
|
+
|
|
126
|
+
- `inputProvenance`: where the request came from, when it was captured, and why
|
|
127
|
+
it remains untrusted until the local review layer regenerates and verifies it.
|
|
128
|
+
- `sourceReferences`: source metadata for pinned SDK registries, verified mainnet
|
|
129
|
+
onchain metadata, wallet reads, quote evidence, simulation, validated request
|
|
130
|
+
facts, or explicit user choices. A `sourceReferences` record is not itself a
|
|
131
|
+
value-bearing fact. It identifies where a typed evidence claim came from.
|
|
132
|
+
- `evidenceClaims`: typed value-bearing claims for every safety-critical fact
|
|
133
|
+
used by the payload. Each claim has a `factKind`, a `sourceEvidenceId` pointing
|
|
134
|
+
to `sourceReferences[].id`, and the value fields required for that fact. The
|
|
135
|
+
schema validates the claim against the safety-critical fact matrix and then
|
|
136
|
+
validates that payload fields match their referenced claim values.
|
|
137
|
+
- `rawQuantities`: raw integer strings plus normalized Sui coin type, verified
|
|
138
|
+
decimals, and unit source. `amountClaimId` must point to a
|
|
139
|
+
`raw_quantity_amount` claim whose role, raw amount, and normalized coin type
|
|
140
|
+
match the payload. Unit `unitClaimId` must point to a `unit_metadata` claim
|
|
141
|
+
whose decimals, normalized coin type, and metadata source match the payload.
|
|
142
|
+
Display amounts remain presentation-only.
|
|
143
|
+
- `gas`: review-time simulation evidence for gas quantities or a concrete
|
|
144
|
+
unresolved reason. `gasBudgetRaw` and `gasUsedRaw` must point to
|
|
145
|
+
`raw_quantity_amount` claims with `gas_budget` and `gas_used` roles, the Sui
|
|
146
|
+
gas coin type, and raw MIST units. An unresolved gas status must point to a
|
|
147
|
+
`gas_unresolved_status` claim. Gas object ownership must point to
|
|
148
|
+
`object_ownership` claims whose ownership status is `owned_by_account`.
|
|
149
|
+
`gasUsedRaw` is the nonnegative net simulation cost. If storage rebates exceed
|
|
150
|
+
costs, omit this optional unsigned quantity and its claim; do not clamp it to
|
|
151
|
+
zero. The verified gas budget remains available, and the review simulation
|
|
152
|
+
retains the exact cost/rebate components and signed balance changes.
|
|
153
|
+
- `expiry`: review-time expiry status. `current` and `expired` require
|
|
154
|
+
`checkedAt`, `expiresAt`, and `evidenceClaimId`; `current` requires
|
|
155
|
+
`expiresAt` after `checkedAt`, and `expired` requires `expiresAt` at or before
|
|
156
|
+
`checkedAt`. The referenced `expiry_status` claim must match the payload and
|
|
157
|
+
must reference a `sourceReferences` record with `checkedAt` and `expiresAt`.
|
|
158
|
+
`not_provided` and `not_applicable` must omit `expiresAt`, include
|
|
159
|
+
`evidenceClaimId` and `reason`, and reference an `expiry_status` claim backed
|
|
160
|
+
by `checkedAt` and `expiryStatus`.
|
|
161
|
+
- `slippageOrMinOut`: quote-linked max slippage and minimum-output policy when
|
|
162
|
+
quote evidence is used. `quoteEvidenceClaimId` must point to a `quote_min_out`
|
|
163
|
+
claim whose `quoteEvidenceId` and `minOutRaw` match the payload.
|
|
164
|
+
`policySource: "user_explicit"` requires a separate `policyEvidenceClaimId`
|
|
165
|
+
pointing to a `slippage_policy` claim backed by `user_explicit_choice` fields
|
|
166
|
+
including `maxSlippageBps` and `userSelection`.
|
|
167
|
+
`policySource: "adapter_policy_from_quote_evidence"` requires
|
|
168
|
+
`policyEvidenceClaimId` pointing to a `slippage_policy` claim backed by quote
|
|
169
|
+
evidence fields including `maxSlippageBps` and `minOutRaw`. If `minOutRaw` or
|
|
170
|
+
`maxSlippageBps` appears in the payload, it must have the matching typed claim;
|
|
171
|
+
stale or missing status does not make an unclaimed scalar safe to use.
|
|
172
|
+
`minOutRaw` must also match a `rawQuantities[]` entry with role
|
|
173
|
+
`minimum_output` so the raw integer has normalized coin type and verified
|
|
174
|
+
decimals.
|
|
175
|
+
- `objectOwnership`: account-bound object ownership or shared-object facts. Each
|
|
176
|
+
object must point to an `object_ownership` claim whose object id, owner account,
|
|
177
|
+
and ownership status match the payload.
|
|
178
|
+
- `simulation`: the public Sui gRPC `transactionExecutionService.simulateTransaction`
|
|
179
|
+
with validation checks enabled, identical returned transaction BCS and matching
|
|
180
|
+
effects digest. The required normalized evidence fields are `effects`,
|
|
181
|
+
`balanceChanges`, `objectTypes`, and `transaction`. The simulation payload must point to a `simulation_result`
|
|
182
|
+
claim whose provider, status, required fields, missing fields, and failure
|
|
183
|
+
reason match the payload.
|
|
184
|
+
- `humanReadableReview`: the fields a human must see before wallet
|
|
185
|
+
authorization, matching the review-model concepts already exposed for
|
|
186
|
+
non-signable proposal review.
|
|
187
|
+
- `outputBoundary`: the MCP and review UI exposure limit. Human-readable review,
|
|
188
|
+
PTB visualization artifacts, diagnostics, and status checks are allowed.
|
|
189
|
+
The required prohibited set is executable transaction material, serialized
|
|
190
|
+
transaction material, wallet signature requests, private-key material, wallet
|
|
191
|
+
authorization, signing data, signing readiness, and payment execution
|
|
192
|
+
readiness. Each contract must include the whole prohibited set.
|
|
193
|
+
|
|
194
|
+
## Safety-Critical Fact Matrix
|
|
195
|
+
|
|
196
|
+
`SAFETY_CRITICAL_FACT_MATRIX` in `src/core/action/signableAdapterContract.ts`
|
|
197
|
+
is the contract's validation source of truth.
|
|
198
|
+
|
|
199
|
+
It defines the required source kind and source fields for these fact kinds:
|
|
200
|
+
|
|
201
|
+
- `raw_quantity_amount`, keyed by role: input, expected output, minimum output,
|
|
202
|
+
gas budget, gas used, fee, and balance delta;
|
|
203
|
+
- `unit_metadata`, keyed by metadata source;
|
|
204
|
+
- `gas_unresolved_status`;
|
|
205
|
+
- `expiry_status`, keyed by status;
|
|
206
|
+
- `quote_min_out`;
|
|
207
|
+
- `slippage_policy`, keyed by policy source;
|
|
208
|
+
- `object_ownership`;
|
|
209
|
+
- `simulation_result`.
|
|
210
|
+
|
|
211
|
+
Payload fields do not cite `sourceReferences` records directly as proof. They cite
|
|
212
|
+
typed evidence claims, and those claims cite `sourceReferences` records. The schema
|
|
213
|
+
rejects payload values that do not match their typed claims.
|
|
214
|
+
|
|
215
|
+
## Consumer Invariant Matrix
|
|
216
|
+
|
|
217
|
+
`CONSUMER_INVARIANT_MATRIX` in
|
|
218
|
+
`src/core/action/signableAdapterContract.ts` defines extra requirements for
|
|
219
|
+
payload fields that consume typed claims. It is separate from
|
|
220
|
+
`SAFETY_CRITICAL_FACT_MATRIX`.
|
|
221
|
+
|
|
222
|
+
`SAFETY_CRITICAL_FACT_MATRIX` answers whether a typed claim has the required
|
|
223
|
+
source kind and source fields. `CONSUMER_INVARIANT_MATRIX` answers whether that
|
|
224
|
+
claim is valid for a specific payload use.
|
|
225
|
+
|
|
226
|
+
Current consumer invariants are:
|
|
227
|
+
|
|
228
|
+
- `gas.gasBudgetClaimId` must reference a `raw_quantity_amount` claim with role
|
|
229
|
+
`gas_budget`, matching raw amount, and Sui gas coin type. The raw unit is MIST.
|
|
230
|
+
- `gas.gasUsedClaimId` must reference a `raw_quantity_amount` claim with role
|
|
231
|
+
`gas_used`, matching raw amount, and Sui gas coin type. The raw unit is MIST.
|
|
232
|
+
- `gas.gasObjects[].ownershipClaimId` must reference an `object_ownership` claim
|
|
233
|
+
with matching object id, matching owner account, and
|
|
234
|
+
`ownership: "owned_by_account"`.
|
|
235
|
+
|
|
236
|
+
The current contract does not prove that a gas object is a `Coin<SUI>` object
|
|
237
|
+
type because the object-ownership claim does not carry object type evidence.
|
|
238
|
+
An adapter must not use object ownership alone as gas coin type evidence.
|
|
239
|
+
|
|
240
|
+
## PTB Visualization Artifact
|
|
241
|
+
|
|
242
|
+
The PTB visualization contract is for explaining a locally generated
|
|
243
|
+
transaction shape before wallet authorization. It is not wallet handoff.
|
|
244
|
+
|
|
245
|
+
The artifact may contain:
|
|
246
|
+
|
|
247
|
+
- `generatedAt`;
|
|
248
|
+
- `source`, including adapter id, plan id when available, source kind, renderer
|
|
249
|
+
name, package name, and version;
|
|
250
|
+
- Mermaid `flowchart` text;
|
|
251
|
+
- diagnostics from the adapter, renderer, schema, or simulation;
|
|
252
|
+
- `unsupportedUse`, including transaction-building input, wallet authorization,
|
|
253
|
+
signing data, signing readiness, payment execution readiness, and route
|
|
254
|
+
recommendation;
|
|
255
|
+
- `executableMaterial.included: false`.
|
|
256
|
+
|
|
257
|
+
The artifact must not contain executable transaction material. Mermaid text and
|
|
258
|
+
diagnostic messages are screened for executable-material terms and long encoded
|
|
259
|
+
payloads.
|
|
260
|
+
|
|
261
|
+
## PTB Renderer Status
|
|
262
|
+
|
|
263
|
+
The pinned renderer dependency is `@zktx.io/ptb-model@0.5.0`. The review layer
|
|
264
|
+
converts the stored local transaction material into a Mermaid `flowchart`
|
|
265
|
+
artifact with `rawTransactionToIR` and `transactionIRToMermaid`, only after the
|
|
266
|
+
stored bytes are recomputed to match the bound transaction material commitment;
|
|
267
|
+
a mismatch declines the artifact. The graph is decoded from the stored transaction bytes with no AI or model input in the rendering path, so it reflects the decoded transaction the wallet will receive, not an AI description of it. The artifact passes
|
|
268
|
+
`ptbVisualizationArtifactSchema` screening before exposure and accompanies the
|
|
269
|
+
emitted wallet review contract as `reviewState.ptbVisualization`. PTB
|
|
270
|
+
visualization stays visualization-only evidence: it is not a runtime
|
|
271
|
+
transaction builder, not wallet handoff, and not a signing-readiness surface.
|
|
272
|
+
|
|
273
|
+
The producer emits the Mermaid flowchart as two parallel streams. `mermaid.text`
|
|
274
|
+
keeps raw package addresses for audit and copy. `mermaid.namedText` is a second
|
|
275
|
+
relabeled stream produced by `applyContractNamesToMermaid`
|
|
276
|
+
(`src/core/action/ptbVisualizationProducer.ts`,
|
|
277
|
+
`src/core/action/contractNameRegistry.ts`): it labels registered packages
|
|
278
|
+
(`@deepbook/core`; the Sui framework `std`/`sui`/`sui_system`) and well-known
|
|
279
|
+
objects (`SuiSystemState`, `Clock`, `Random`, `DenyList`, `CoinRegistry`,
|
|
280
|
+
`AccumulatorRoot`) while keeping the raw addresses available. These names are a
|
|
281
|
+
display label, not a safety, ownership, or trust signal, and the on-chain Move
|
|
282
|
+
Registry name is not yet verified on chain.
|
|
283
|
+
|
|
284
|
+
## Adapter Registration And Stage Vocabulary
|
|
285
|
+
|
|
286
|
+
Review adapters register through `ReviewAdapterDescriptor` entries in
|
|
287
|
+
`src/adapters/reviewAdapters.ts` (`buildSupportedReviewAdapterDescriptors`).
|
|
288
|
+
A descriptor supplies the adapter id, protocol, action kind, stage catalog id,
|
|
289
|
+
and the evidence computer; action-plan factories live in the adapter module
|
|
290
|
+
and are wired by the MCP layer. The platform keeps the
|
|
291
|
+
safety gates non-delegable: the typed evidence claim matrices, the commitment
|
|
292
|
+
equality gate, the adapter lifecycle validator registry
|
|
293
|
+
(`src/adapters/adapterLifecycleValidators.ts`), and the digest-gated byte
|
|
294
|
+
handoff all run outside adapter code. `src/core` contains no adapter imports;
|
|
295
|
+
a source-policy test enforces that boundary.
|
|
296
|
+
|
|
297
|
+
Stage vocabulary is a cross-adapter contract. Every stage catalog that reports
|
|
298
|
+
public review evidence must use these stage ids for these concepts, because the
|
|
299
|
+
core review-state schema binds public fields to them:
|
|
300
|
+
|
|
301
|
+
- `transaction_material_build_or_verify`: local unsigned material exists.
|
|
302
|
+
- `digest_commitment`: the Sui transaction digest is bound to the material.
|
|
303
|
+
- `object_ownership`: object ownership evidence is verified.
|
|
304
|
+
- `human_readable_review`: required before `reviewState.humanReadableReview`.
|
|
305
|
+
- `review_time_simulation`: required before `reviewState.simulation`.
|
|
306
|
+
|
|
307
|
+
Adapter acceptance gate: a new protocol enters as read-only tools or
|
|
308
|
+
non-signable proposal review first. A signable adapter is accepted only when it
|
|
309
|
+
produces every required evidence stage from independently built or verified
|
|
310
|
+
material, passes `transactionReviewDataSchema` without placeholder
|
|
311
|
+
values, and fails closed when any evidence is missing. Protocol names stay out
|
|
312
|
+
of public docs, runtime guidance, and MCP resources until a concrete
|
|
313
|
+
implementation or support decision exists.
|
|
314
|
+
|
|
315
|
+
## Verification
|
|
316
|
+
|
|
317
|
+
Tests must keep this contract in place before any adapter can use it:
|
|
318
|
+
|
|
319
|
+
- schema tests for required provenance, source-of-truth, raw quantity, gas,
|
|
320
|
+
expiry, slippage or minimum output, object ownership, simulation, and
|
|
321
|
+
human-readable review fields;
|
|
322
|
+
- tests that reject duplicate `sourceReferences[].id` and `evidenceClaims[].id`
|
|
323
|
+
values;
|
|
324
|
+
- tests that reject every payload claim reference that does not resolve to a
|
|
325
|
+
typed `evidenceClaims[].id`;
|
|
326
|
+
- tests that reject every `evidenceClaims[].sourceEvidenceId` that does not
|
|
327
|
+
resolve to a `sourceReferences[].id`;
|
|
328
|
+
- tests that reject safety-critical claims whose source references resolve to the
|
|
329
|
+
wrong source kind or to records missing the required fields for that claim;
|
|
330
|
+
- tests that reject payload values whose raw amounts, decimals, gas quantities,
|
|
331
|
+
expiry values, minimum output, slippage policy, object ownership, or simulation
|
|
332
|
+
status do not match their typed evidence claims;
|
|
333
|
+
- tests that reject metadata-only records as raw amount evidence and reject
|
|
334
|
+
user-explicit slippage policy claims without explicit user-choice evidence;
|
|
335
|
+
- tests that reject raw signable quantity assets without normalized Sui coin
|
|
336
|
+
types;
|
|
337
|
+
- tests that reject min-out or slippage scalar fields when they do not have typed
|
|
338
|
+
evidence claims;
|
|
339
|
+
- tests that reject `minOutRaw` when it does not match a `rawQuantities[]` entry
|
|
340
|
+
with role `minimum_output`;
|
|
341
|
+
- tests that require `gasBudgetRaw` and `gasUsedRaw` to use
|
|
342
|
+
`raw_quantity_amount` claims with gas roles, the Sui gas coin type, and raw
|
|
343
|
+
MIST units, or require unresolved gas status to use a `gas_unresolved_status`
|
|
344
|
+
claim;
|
|
345
|
+
- tests that reject gas object references backed by object-ownership claims whose
|
|
346
|
+
ownership status is not `owned_by_account`;
|
|
347
|
+
- tests that require every mandatory prohibited output boundary and every
|
|
348
|
+
mandatory PTB unsupported-use boundary;
|
|
349
|
+
- tests that reject `current` or `expired` expiry status without timestamp
|
|
350
|
+
evidence, source evidence, matching source fields, and the required
|
|
351
|
+
`checkedAt`/`expiresAt` time relationship;
|
|
352
|
+
- tests that reject `not_provided` or `not_applicable` expiry status when it
|
|
353
|
+
includes an `expiresAt` timestamp or omits the reason and source evidence for
|
|
354
|
+
why timestamp evidence is unavailable;
|
|
355
|
+
- tests that require failed or unavailable simulation evidence to include a
|
|
356
|
+
concrete `failureReason`;
|
|
357
|
+
- tests that reject display amounts, exponent notation, or floating-point values
|
|
358
|
+
as raw quantities;
|
|
359
|
+
- tests that reject PTB visualization artifacts containing executable-material
|
|
360
|
+
terms or long encoded payloads;
|
|
361
|
+
- MCP/review output tests using the shared forbidden-field-name policy;
|
|
362
|
+
- documentation tests that keep PTB visualization described as visualization
|
|
363
|
+
only, not transaction material, signing readiness, or payment execution
|
|
364
|
+
readiness.
|
|
365
|
+
|
|
366
|
+
## Transaction funding and ownership
|
|
367
|
+
|
|
368
|
+
The supported swap adapters retain the SDK's coin-object and address-balance
|
|
369
|
+
selection. The private ownership evidence verifies the stored transaction's
|
|
370
|
+
sender, gas payer, real object references, address withdrawals, and gas funding
|
|
371
|
+
against the reviewed account and verified mainnet source. The same description
|
|
372
|
+
must match the checks-enabled simulation and the material rechecked for admission.
|
|
373
|
+
|
|
374
|
+
An empty gas payment array means address-balance gas; it is not missing gas
|
|
375
|
+
evidence. It requires a mainnet-bound ValidDuring epoch window and address SUI
|
|
376
|
+
covering both explicit SUI withdrawals and the gas budget. A gas reservation
|
|
377
|
+
reference is an address-balance reservation, not a Coin<SUI> object. Its account,
|
|
378
|
+
asset, chain, amount and epoch are verified; any real gas coins alongside it
|
|
379
|
+
retain their ownership/type checks. Explicit address withdrawals and reservations
|
|
380
|
+
are summed per coin type without counting the gas budget twice. Observed balances
|
|
381
|
+
are review-time facts, not locked funds or execution guarantees.
|
|
382
|
+
|
|
383
|
+
Only real gas coins produce `gas.gasObjects` and object-ownership claims. The
|
|
384
|
+
public optional field remains absent when no such objects are used. Private
|
|
385
|
+
funding evidence is required in either case; omitting all funding checks does not
|
|
386
|
+
produce a valid review. The existing human review evidence explains the funding
|
|
387
|
+
form without publishing private artifacts or creating signing authority.
|
|
388
|
+
|
|
389
|
+
Different gas owners, sponsor withdrawals, unsupported reservation formats, and
|
|
390
|
+
unverified funding remain blocked. Supported adapters still require the same quote,
|
|
391
|
+
amount, ownership, human review, simulation, wallet approval, and digest checks.
|
|
392
|
+
|
|
393
|
+
New review evidence names `client.transactionExecutionService.simulateTransaction`
|
|
394
|
+
as its provider. The previous `client.core.simulateTransaction` provider remains
|
|
395
|
+
parseable in stored public history; it is not a fallback for new reviews. Returned
|
|
396
|
+
BCS is compared privately and is never added to evidence, cards, backups or logs.
|