feat(sdk): route balance reads through transport-agnostic Core API (gRPC migration Stage 1)#98
Open
ngna3007 wants to merge 1 commit into
Open
feat(sdk): route balance reads through transport-agnostic Core API (gRPC migration Stage 1)#98ngna3007 wants to merge 1 commit into
ngna3007 wants to merge 1 commit into
Conversation
gRPC migration Stage 1 (SPEC_FULL_GRPC_MIGRATION). Mysten deactivates the public Sui JSON-RPC fullnode on 2026-07-31. Both SuiJsonRpcClient and SuiGrpcClient expose the same `.core` CoreClient, so balance reads move onto `client.core.*` and soak on JSON-RPC before flipping T2000_TRANSPORT=grpc. - balance.ts: fetchSuiPrice + queryBalance use client.core.getBalance / getObject; param widened to the transport-agnostic ClientWithCoreApi. Adds resetSuiPriceCache() (test/probe seam for the module-level price cache). - utils/sui.ts: getSuiReadClient() flip seam keyed on T2000_TRANSPORT (default jsonrpc, fail-safe); a custom rpcUrl does not carry to the gRPC branch, so a non-default fullnode needs T2000_GRPC_URL (documented inline). getSuiGraphQLClient() stub for Stage 2 history.ts; DEFAULT_GRAPHQL_URL. - t2000.ts: readClient field routes the two queryBalance call sites; writes and execution stay on the JSON-RPC client until Stage 4. - index.ts: export queryBalance (canonical SDK balance reader), resetSuiPriceCache, and getSuiGraphQLClient. - tests: balance.test.ts (Core response shapes) + getSuiReadClient transport-selector tests in sui.test.ts. - grpc-parity-probe.mjs: Stage 1 gate proves parity across both transports, multiple wallet shapes, AND both call orders. Resets the price cache before each read so each transport exercises its own core.getObject, compares the full BalanceResponse (usdEquiv within a small tolerance, not stripped), and checks the Cetus pool json shape head-on. Sets a non-zero exit code on failure so CI / a canary guard can gate on it. Verified byte-identical on mainnet. Writes and history reads are intentionally untouched (Stages 2 and 4).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
gRPC migration Stage 1 (
SPEC_FULL_GRPC_MIGRATION). Mysten deactivates the public Sui JSON-RPC fullnode on 2026-07-31. BothSuiJsonRpcClientandSuiGrpcClientexpose the same.coreCoreClient, so this routes the balance read path ontoclient.core.*. It soaks on JSON-RPC today and flips to gRPC via a single env flag — a near-no-op.Scope is deliberately one read path. Writes, execution, and history are untouched (Stages 2 and 4).
Changes
balance.ts—fetchSuiPrice+queryBalanceuseclient.core.getBalance/getObject(shape drift:.totalBalance→.balance.balance;.data.content.fields→.object.json). Param widened to the transport-agnosticClientWithCoreApi. AddsresetSuiPriceCache()(test/probe seam for the module-level price cache).utils/sui.ts—getSuiReadClient()flip seam keyed onT2000_TRANSPORT(defaultjsonrpc, fail-safe on unrecognized values). A customrpcUrldoes not carry to the gRPC branch, so a non-default fullnode needsT2000_GRPC_URL(documented inline). AddsgetSuiGraphQLClient()stub for Stage 2history.ts+DEFAULT_GRAPHQL_URL.t2000.ts— newreadClientfield routes the twoqueryBalancecall sites; writes/execution stay onthis.client(JSON-RPC) until Stage 4.index.ts— exportqueryBalance(canonical SDK balance reader),resetSuiPriceCache,getSuiGraphQLClient.balance.test.ts(Core response shapes) +getSuiReadClienttransport-selector tests insui.test.ts.grpc-parity-probe.mjs— Stage 1 gate: parity across both transports, multiple wallet shapes, and both call orders. Resets the price cache before each read so each transport exercises its owncore.getObject; compares the fullBalanceResponse(usdEquiv within a small tolerance, not stripped); checks the Cetus pool json shape head-on; non-zero exit on failure for CI/canary gating.How to flip
Off by default. Set
T2000_TRANSPORT=grpcto route balance reads over gRPC; unset to roll back instantly (no redeploy).Verification
pnpm --filter @t2000/sdk typecheck— cleanpnpm --filter @t2000/engine typecheck— cleanReviewed
Two independent Codex review rounds: a price-cache gate blind-spot (gRPC
getObjectskipped via shared cache) and a probe exit-code gap were both found and fixed; no outstanding code issues.Not in this PR (ops)
Production soak / canary — deploy + flip
T2000_TRANSPORT=grpcon a canary surface, watch parity + latency, then widen.