Skip to content

Fix TS SDK raw RPC drift and on-chain balance surface#698

Merged
ihsraham merged 3 commits into
mainfrom
ts-sdk-core-truth-fixes
Apr 21, 2026
Merged

Fix TS SDK raw RPC drift and on-chain balance surface#698
ihsraham merged 3 commits into
mainfrom
ts-sdk-core-truth-fixes

Conversation

@ihsraham
Copy link
Copy Markdown
Collaborator

@ihsraham ihsraham commented Apr 21, 2026

This is part of the ongoing refinements to the TS SDKs, focused on the main TypeScript SDK.

It adds a high-level getOnChainBalance(...) surface, removes the unsupported raw app_sessions.v1.close_app_session RPC from the TS SDK, tightens the README parity wording, and aligns the package-local test and lint setup so the TS SDK can be validated cleanly.

release note: this removes the previously exposed raw app_sessions.v1.close_app_session method, request/response types, and client helper from @yellow-org/sdk. that RPC is not supported by clearnode. app session close continues to be modeled through submit_app_state with close intent.

Summary by CodeRabbit

  • New Features

    • Added on-chain balance query capability to retrieve token and native asset balances.
  • Removals

    • Removed deprecated app session closure RPC endpoint.
  • Documentation

    • Updated SDK compatibility documentation to clarify supported features.
  • Tests

    • Added comprehensive unit tests for new on-chain balance query functionality.
  • Chores

    • Updated build and linting configurations for improved ECMAScript module support.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

📝 Walkthrough

Walkthrough

The pull request adds a new client method for querying on-chain token balances, removes the app session close RPC functionality, transitions the TypeScript SDK to ESM module support with updated build and test configurations, and adds corresponding test coverage. Documentation reflects the revised feature scope.

Changes

Cohort / File(s) Summary
Build & Test Configuration
eslint.config.cjs, jest.config.cjs, package.json
Updated Jest configuration to use ESM-focused preset with --experimental-vm-modules flag, added ESLint flat config for TypeScript with recommended rules, and revised npm scripts to explicitly pass config files and enable ESM treatment of .ts files.
Documentation
README.md
Adjusted feature claims to remove "100% compatibility" assertion and added new "On-Chain Queries" section documenting the getOnChainBalance method.
On-Chain Balance Feature
src/client.ts
Added new public async method getOnChainBalance(chainId, asset, wallet) that initializes the blockchain client and delegates to blockchainClient.getTokenBalance.
RPC Layer Removal
src/rpc/api.ts, src/rpc/client.ts, src/rpc/methods.ts
Removed AppSessionsV1CloseAppSession request/response interfaces, method constant, and corresponding RPCClient method implementation.
Module Import Updates
src/core/state_advancer.ts
Changed internal imports from extensionless paths to explicit .js file specifiers for ESM compatibility.
Test Coverage
test/unit/client.test.ts
Added comprehensive unit tests for getOnChainBalance covering initialization behavior, asynchronous client registration, and error propagation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • dimast-x
  • philanton

Poem

🐰 Hopping through modules with ESM delight,
New balances queried, on-chain in sight,
Sessions close gracefully, removed from the trace,
Test files keep watch o'er this refactored space!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main changes: removal of raw RPC drift (app_sessions.v1.close_app_session) and addition of the on-chain balance surface (getOnChainBalance method).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ts-sdk-core-truth-fixes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ihsraham ihsraham force-pushed the ts-sdk-core-truth-fixes branch from bf853e3 to 9b51b68 Compare April 21, 2026 08:23
@ihsraham ihsraham changed the base branch from feat/middle-audit-deploy to main April 21, 2026 08:23
@ihsraham
Copy link
Copy Markdown
Collaborator Author

pushed a small follow up here. added two more getonchainbalance tests so we cover init ordering and error propagation, and updated the pr description with an explicit release note for the raw close_app_session removal since there is no package changelog file in this repo to land that in.

@nksazonov
Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdk/ts/package.json (1)

61-67: ⚠️ Potential issue | 🟠 Major

Remove jest-util from dependencies — it is an internal Jest helper package that should never be a runtime dependency.

jest-util is an internal utility used by Jest's own packages and is already pulled in transitively. It has no place in the SDK's runtime dependencies and will unnecessarily pollute the dependency tree of every consumer. The initial search confirms no code in src/ or test/ directly imports jest-util, so it can be safely removed entirely.

Proposed fix
     "dependencies": {
         "abitype": "^1.2.3",
         "decimal.js": "^10.4.3",
-        "jest-util": "^30.3.0",
         "viem": "^2.46.1",
         "zod": "^4.3.6"
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/ts/package.json` around lines 61 - 67, Remove the inappropriate runtime
dependency "jest-util" from the package.json "dependencies" block (the entry
currently alongside "abitype", "decimal.js", "viem", and "zod"); delete the
"jest-util" line, run your package manager to update the lockfile
(npm/yarn/pnpm) so the lockfile no longer lists it, and ensure no src/ or test/
files import "jest-util" (search for usages) before committing the change.
🧹 Nitpick comments (2)
sdk/ts/test/unit/client.test.ts (1)

5-83: Tests cover the new surface well; one small robustness tweak on the init-ordering test.

The three cases (delegation, init-ordering, error propagation) are appropriately scoped, and using Object.create(Client.prototype) with injected internals is a reasonable way to avoid standing up an RPC/WebSocket stack for a pure delegator. Two observations:

  1. The init-ordering test relies on ordering in the microtask queue when asserting getTokenBalance has not been called yet (line 55). That assertion runs synchronously right after client.getOnChainBalance(...) is invoked, before any awaited continuation runs, so it's correct — but a Promise.resolve() tick before the assertion would make the "waits for initialization" intent more explicit and less reliant on JS scheduling semantics.

  2. These tests reach into private-ish fields (blockchainClients, initializeBlockchainClient). That's fine for a unit test of this size, but if the internal caching shape changes later (e.g., replaced by a factory), all three tests will need updating in lockstep. Consider a follow-up with a thin seam (e.g., an injectable factory) when/if more balance/chain methods land.

♻️ Optional tightening of the ordering assertion
         const balancePromise = client.getOnChainBalance(chainId, 'usdc', wallet);

+        // Let any synchronous microtasks settle so the assertion reflects
+        // the explicit "awaiting initializeBlockchainClient" state.
+        await Promise.resolve();
         expect(initializeBlockchainClient).toHaveBeenCalledWith(chainId);
         expect(getTokenBalance).not.toHaveBeenCalled();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/ts/test/unit/client.test.ts` around lines 5 - 83, The init-ordering test
should explicitly yield a microtask before asserting getTokenBalance hasn't been
called: after invoking client.getOnChainBalance(...) (which internally calls
client.initializeBlockchainClient), await a Promise.resolve() (or use
process.nextTick()/setImmediate equivalent) to ensure the initialization
microtask runs before checking that getTokenBalance wasn't invoked; this change
touches the test that calls client.getOnChainBalance, asserts
initializeBlockchainClient was called, and then checks getTokenBalance, so add
the single microtask yield between those steps to make the ordering assert
deterministic.
sdk/ts/eslint.config.cjs (1)

22-23: Consider a narrower relaxation of no-unused-vars.

Turning off @typescript-eslint/no-unused-vars project-wide silences genuinely unused symbols in new code, not just the intended RPC wire-type cases. A common middle ground is keeping the rule enabled with an underscore ignore pattern:

♻️ Proposed refactor
-            '@typescript-eslint/no-explicit-any': 'off',
-            '@typescript-eslint/no-unused-vars': 'off',
+            '@typescript-eslint/no-explicit-any': 'off',
+            '@typescript-eslint/no-unused-vars': [
+                'warn',
+                { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' },
+            ],

no-explicit-any being off is defensible per the repo guideline allowing any for RPC wire types, so leaving that as-is is fine.

As per coding guidelines: "Strict TypeScript — no any unless unavoidable (e.g., RPC wire types)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/ts/eslint.config.cjs` around lines 22 - 23, The rule
'@typescript-eslint/no-unused-vars' is currently turned off broadly; re-enable
it and apply an underscore-ignore pattern so only intentionally prefixed unused
symbols are suppressed. Update the ESLint config entry for
'@typescript-eslint/no-unused-vars' to a strict setting (error or warn) with
options like argsIgnorePattern, varsIgnorePattern (and
caughtErrorsIgnorePattern) set to '^_' so RPC wire-type uses of `any` remain
allowed while genuine unused symbols are still reported; leave
'@typescript-eslint/no-explicit-any' as-is.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@sdk/ts/package.json`:
- Around line 61-67: Remove the inappropriate runtime dependency "jest-util"
from the package.json "dependencies" block (the entry currently alongside
"abitype", "decimal.js", "viem", and "zod"); delete the "jest-util" line, run
your package manager to update the lockfile (npm/yarn/pnpm) so the lockfile no
longer lists it, and ensure no src/ or test/ files import "jest-util" (search
for usages) before committing the change.

---

Nitpick comments:
In `@sdk/ts/eslint.config.cjs`:
- Around line 22-23: The rule '@typescript-eslint/no-unused-vars' is currently
turned off broadly; re-enable it and apply an underscore-ignore pattern so only
intentionally prefixed unused symbols are suppressed. Update the ESLint config
entry for '@typescript-eslint/no-unused-vars' to a strict setting (error or
warn) with options like argsIgnorePattern, varsIgnorePattern (and
caughtErrorsIgnorePattern) set to '^_' so RPC wire-type uses of `any` remain
allowed while genuine unused symbols are still reported; leave
'@typescript-eslint/no-explicit-any' as-is.

In `@sdk/ts/test/unit/client.test.ts`:
- Around line 5-83: The init-ordering test should explicitly yield a microtask
before asserting getTokenBalance hasn't been called: after invoking
client.getOnChainBalance(...) (which internally calls
client.initializeBlockchainClient), await a Promise.resolve() (or use
process.nextTick()/setImmediate equivalent) to ensure the initialization
microtask runs before checking that getTokenBalance wasn't invoked; this change
touches the test that calls client.getOnChainBalance, asserts
initializeBlockchainClient was called, and then checks getTokenBalance, so add
the single microtask yield between those steps to make the ordering assert
deterministic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1a69fb4e-54ce-4526-9c84-cf89542796bc

📥 Commits

Reviewing files that changed from the base of the PR and between bbc4f55 and 6f3afce.

📒 Files selected for processing (10)
  • sdk/ts/README.md
  • sdk/ts/eslint.config.cjs
  • sdk/ts/jest.config.cjs
  • sdk/ts/package.json
  • sdk/ts/src/client.ts
  • sdk/ts/src/core/state_advancer.ts
  • sdk/ts/src/rpc/api.ts
  • sdk/ts/src/rpc/client.ts
  • sdk/ts/src/rpc/methods.ts
  • sdk/ts/test/unit/client.test.ts
💤 Files with no reviewable changes (3)
  • sdk/ts/src/rpc/methods.ts
  • sdk/ts/src/rpc/client.ts
  • sdk/ts/src/rpc/api.ts

@ihsraham ihsraham merged commit 8681166 into main Apr 21, 2026
8 checks passed
@ihsraham ihsraham deleted the ts-sdk-core-truth-fixes branch April 21, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants