Skip to content

YNU-869: Guard TS SDK drift and CI validation#701

Merged
nksazonov merged 6 commits into
mainfrom
ts-sdk-drift-guards
May 5, 2026
Merged

YNU-869: Guard TS SDK drift and CI validation#701
nksazonov merged 6 commits into
mainfrom
ts-sdk-drift-guards

Conversation

@ihsraham
Copy link
Copy Markdown
Collaborator

@ihsraham ihsraham commented Apr 21, 2026

this is part of the ts sdk refinement work.

it does three things:

  • removes the unsupported channels.v1.get_states surface from shared rpc, ts raw rpc, and the protocol docs
  • adds a static drift test in sdk/ts to keep the ts raw rpc surface aligned with pkg/rpc and the live clearnode router
  • re-enables sdk validation on main prs and pushes for both sdk/ts and sdk/ts-compat, using the real package paths and the full typecheck / test / lint / build gate

Summary by CodeRabbit

  • Bug Fixes

    • Removed the channels.get_states RPC method and its client interfaces (API, SDK clients, and related docs/examples).
  • Tests

    • Added automated test to ensure RPC method lists stay aligned across implementations.
    • Expanded CI validations to include typecheck, lint, and CI builds for SDKs.
  • Chores

    • CI updated to run separate jobs for TS SDK and TS-compat variants; added CI-only build scripts.
  • SDK

    • TS-compat client now prefers embedded appDefinition payloads when mapping app session data.

Additional compat fix discovered during stress Clearnode testing:

While wiring cosign-demo to wss://clearnode-stress.yellow.org/v1/ws, getAppSessionsList() exposed a compat drift: current v1 SDK sessions return participant/quorum/nonce data under appDefinition, but compat was still reading the old flat participants shape. This PR now maps appDefinition.participants first and keeps a flat-shape fallback for older callers.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

📝 Walkthrough

Walkthrough

Removed the deprecated channels.v1.get_states RPC surface across API, Go, and TypeScript; updated CI to run separate TS SDK and TS-compat validation jobs (including typecheck/lint/build); added ts/ts-compat build scripts; and introduced a Jest drift-guard test ensuring RPC method parity between Go and TS.

Changes

Cohort / File(s) Summary
CI / Workflows
/.github/workflows/main-pr.yml, /.github/workflows/main-push.yml, /.github/workflows/v1-push.yml, /.github/workflows/test-sdk.yml
Replaced/commented single test-sdk with test-sdk-ts and test-sdk-compat reusing test-sdk.yml; made project-path/project-name inputs required, added optional bootstrap-project-path; job renamed to "Validate" and now runs optional bootstrap install/build, npm test, lint, and build:ci.
API spec
docs/api.yaml
Removed channels.v1.get_states API method definition (request params, response schema, and related error).
Go RPC layer
pkg/rpc/api.go, pkg/rpc/client.go, pkg/rpc/methods.go, pkg/rpc/client_test.go, pkg/rpc/README.md
Deleted ChannelsV1GetStatesRequest/ChannelsV1GetStatesResponse types, ChannelsV1GetStates client method, ChannelsV1GetStatesMethod constant, related unit test, and example usage in README.
TypeScript SDK
sdk/ts/src/rpc/api.ts, sdk/ts/src/rpc/client.ts, sdk/ts/src/rpc/methods.ts
Removed ChannelsV1GetStatesRequest/ChannelsV1GetStatesResponse interfaces, the channelsV1GetStates RPC client method, and the ChannelsV1GetStatesMethod constant.
RPC drift-guard test
sdk/ts/test/unit/rpc-drift.test.ts
Added Jest test that extracts RPC method literals from Go and TS sources and from the router, resolves router constants, and asserts literal parity with deterministic diff output and explicit errors for unresolved router references.
TS compat package & TS package
sdk/ts-compat/package.json, sdk/ts/package.json, sdk/ts-compat/src/client.ts, sdk/ts-compat/test/unit/client.test.ts
Added build:ci script (tsc) to both packages; getAppSessionsList mapping updated to prefer appDefinition payload with fallback to legacy fields; added unit tests validating both new and legacy mappings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

ready

Suggested reviewers

  • dimast-x
  • nksazonov
  • philanton

Poem

🐇 I hopped through lines both old and new,
I pruned a call and made the tests true.
CI splits paths, TypeScript compiles,
A drift-guard hums across the files.
The rabbit cheers — code clean and new!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.
Title check ✅ Passed The title accurately reflects the main changes: removing TS SDK drift (removing unsupported channels.v1.get_states API) and adding CI validation guards for the TypeScript SDK.

✏️ 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-drift-guards

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/main-pr.yml:
- Around line 26-31: The test-sdk-compat job runs before the TS SDK build
completes causing typecheck to fail; update the workflow so test-sdk-compat
depends on the TS SDK build by adding needs: test-sdk-ts to the test-sdk-compat
job (or alternatively merge the two jobs into one sequential job), ensuring the
job name test-sdk-compat has a needs reference to test-sdk-ts so sdk/ts/dist/
exists before the compat job runs.

In @.github/workflows/test-sdk.yml:
- Around line 39-49: The workflow runs tests twice for sdk/ts because
package.json's "build" executes "npm run test && tsc"; remove or conditionalize
the standalone "Run tests" step (the step named "Run tests" that runs "npm
test") so sdk/ts relies on the subsequent "Build" step to run tests, and retain
an explicit test step only for projects that need it (e.g., sdk/ts-compat).
Update the job to either delete the "Run tests" step or wrap it with a
conditional that checks inputs.project-path (or normalize an allowlist) so only
projects whose build does not run tests execute "npm test".

In `@sdk/ts/test/unit/rpc-drift.test.ts`:
- Around line 20-35: The extractRouterHandlers function currently drops
unresolved router constants silently; change it to fail-fast by detecting any
methodNames for which namedLiterals.get(name) is undefined and throwing (or
asserting) with a clear error listing the unresolved method constant names so
the test surfaces missing/renamed constants; locate the lookup in
extractRouterHandlers (the map namedLiterals and the final map/filter over
methodNames) and replace the silent .filter(Boolean) behavior with an explicit
check that collects missing names and throws if any exist, otherwise return the
resolved set as before.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 86f72b97-6dbf-4888-94bc-2b9419a00f40

📥 Commits

Reviewing files that changed from the base of the PR and between 8681166 and 82ee890.

📒 Files selected for processing (13)
  • .github/workflows/main-pr.yml
  • .github/workflows/main-push.yml
  • .github/workflows/test-sdk.yml
  • docs/api.yaml
  • pkg/rpc/README.md
  • pkg/rpc/api.go
  • pkg/rpc/client.go
  • pkg/rpc/client_test.go
  • pkg/rpc/methods.go
  • sdk/ts/src/rpc/api.ts
  • sdk/ts/src/rpc/client.ts
  • sdk/ts/src/rpc/methods.ts
  • sdk/ts/test/unit/rpc-drift.test.ts
💤 Files with no reviewable changes (9)
  • pkg/rpc/README.md
  • pkg/rpc/api.go
  • pkg/rpc/client.go
  • sdk/ts/src/rpc/methods.ts
  • pkg/rpc/methods.go
  • docs/api.yaml
  • sdk/ts/src/rpc/client.ts
  • sdk/ts/src/rpc/api.ts
  • pkg/rpc/client_test.go

Comment thread .github/workflows/main-pr.yml
Comment thread .github/workflows/test-sdk.yml Outdated
Comment on lines +39 to +49
- name: Run tests
run: npm test
working-directory: ${{ inputs.project-path }}

- name: Lint
run: npm run lint
working-directory: ${{ inputs.project-path }}

- name: Build
run: npm run build
working-directory: ${{ inputs.project-path }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Double test execution for sdk/tsbuild already runs test.

For sdk/ts, package.json defines "build": "npm run test && tsc", so adding both a npm test step (Line 40) and a npm run build step (Line 48) causes Jest to run twice for that project, unnecessarily lengthening CI. Based on learnings: "Do not run npm test && npm run build in sdk/ts (double-tests; build already runs tests)".

Consider either dropping the standalone test step, or splitting the reusable workflow logic so that sdk/ts relies on npm run build for its test pass while sdk/ts-compat (whose build is plain tsc) keeps the explicit npm test step.

Possible fix (single build step covers tests for sdk/ts; compat would need test kept separately)
-      - name: Run tests
-        run: npm test
-        working-directory: ${{ inputs.project-path }}
-
       - name: Lint
         run: npm run lint
         working-directory: ${{ inputs.project-path }}

       - name: Build
         run: npm run build
         working-directory: ${{ inputs.project-path }}

Note: this requires ensuring sdk/ts-compat's build also triggers tests (or keeping npm test for that project specifically).

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

In @.github/workflows/test-sdk.yml around lines 39 - 49, The workflow runs tests
twice for sdk/ts because package.json's "build" executes "npm run test && tsc";
remove or conditionalize the standalone "Run tests" step (the step named "Run
tests" that runs "npm test") so sdk/ts relies on the subsequent "Build" step to
run tests, and retain an explicit test step only for projects that need it
(e.g., sdk/ts-compat). Update the job to either delete the "Run tests" step or
wrap it with a conditional that checks inputs.project-path (or normalize an
allowlist) so only projects whose build does not run tests execute "npm test".

Comment thread sdk/ts/test/unit/rpc-drift.test.ts
Copy link
Copy Markdown
Contributor

@nksazonov nksazonov left a comment

Choose a reason for hiding this comment

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

Generally good, with some comments

Comment thread sdk/ts/test/unit/rpc-drift.test.ts
Comment thread .github/workflows/test-sdk.yml
Comment thread .github/workflows/test-sdk.yml
Comment thread sdk/ts/test/unit/rpc-drift.test.ts Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cool initiative! Later, we could upgrade this one or/and add something similar for SDK Client (and anything else worth checking integrity)

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.

🧹 Nitpick comments (1)
sdk/ts-compat/test/unit/client.test.ts (1)

1-122: LGTM — focused coverage for both session shapes.

The two scenarios (v1 appDefinition and legacy flat fields) directly exercise the new branch in mapSessions, including bigint → number and Decimal → scaled string conversions per asset decimals. Console spies are installed/restored correctly via beforeEach/afterEach.

One optional nit: consider adding a third case that asserts the retry-without-status fallback behavior (client.ts lines 607–623) when a caller passes a concrete status like 'open', since that path isn't exercised here. Not blocking — can be added in a follow-up.

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

In `@sdk/ts-compat/test/unit/client.test.ts` around lines 1 - 122, Add a third
unit that verifies the "retry without status" fallback in getAppSessionsList:
create a client via makeClient, replace client.innerClient.getAppSessions with a
jest mock that mockRejectedValueOnce an Error-like object representing a 400
failure when called with {wallet, status:'open'} and then mockResolvedValueOnce
a normal { sessions } response for the subsequent call without status; call
client.getAppSessionsList(wallet, 'open') and assert the mock was called twice
(first with status, then without) and that the final returned sessions match the
expected mapped shape; reference getAppSessionsList and
innerClient.getAppSessions in the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@sdk/ts-compat/test/unit/client.test.ts`:
- Around line 1-122: Add a third unit that verifies the "retry without status"
fallback in getAppSessionsList: create a client via makeClient, replace
client.innerClient.getAppSessions with a jest mock that mockRejectedValueOnce an
Error-like object representing a 400 failure when called with {wallet,
status:'open'} and then mockResolvedValueOnce a normal { sessions } response for
the subsequent call without status; call client.getAppSessionsList(wallet,
'open') and assert the mock was called twice (first with status, then without)
and that the final returned sessions match the expected mapped shape; reference
getAppSessionsList and innerClient.getAppSessions in the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 89e0c0f3-d99e-4c20-9ef4-94757b1ea4e8

📥 Commits

Reviewing files that changed from the base of the PR and between 17d4e72 and 0ec5683.

📒 Files selected for processing (4)
  • .github/workflows/test-sdk.yml
  • sdk/ts-compat/src/client.ts
  • sdk/ts-compat/test/unit/client.test.ts
  • sdk/ts/test/unit/rpc-drift.test.ts
✅ Files skipped from review due to trivial changes (2)
  • sdk/ts/test/unit/rpc-drift.test.ts
  • .github/workflows/test-sdk.yml

@nksazonov nksazonov changed the title Guard TS SDK drift and CI validation YNU-869: Guard TS SDK drift and CI validation May 5, 2026
@nksazonov nksazonov merged commit 4adaabe into main May 5, 2026
10 checks passed
@nksazonov nksazonov deleted the ts-sdk-drift-guards branch May 5, 2026 07:50
ihsraham added a commit that referenced this pull request May 6, 2026
This is part of the ongoing refinements to the TS SDKs, focused on the
compat TypeScript SDK. It is now rebased on current `main` after #701.

It makes the compat runtime surface more honest and more useful during
migration:
- direct-mapping legacy RPC helpers emit real v1-compatible payloads
- workflow-only legacy helpers fail fast with clear migration guidance
instead of returning fake wire payloads
- selected legacy client conveniences are restored on top of the current
SDK behavior
- compat amount handling keeps the domains explicit: `transfer()` and
`getBalances()` use canonical asset raw-unit strings, on-chain token
helpers use raw token-unit `bigint`, and app-session allocations stay
human-decimal strings
- the rebase preserves #701 app-session `appDefinition` mapping and
current `nitronode` naming
- runtime-focused compat tests cover wire shape, client mappings, and
amount semantics

Validation run locally:
- `npm --prefix sdk/ts-compat run typecheck`
- `npm --prefix sdk/ts-compat test`
- `npm --prefix sdk/ts-compat run lint`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added on-chain helpers (approve, allowance, token balance) and an
open-channels query; RPC helpers now emit real v1-compatible requests
and normalize envelope responses.

* **Behavior Changes**
* Several legacy helper flows now fail fast as migration shims instead
of returning placeholders.
* App-session submit/close helpers now require an explicit version and
preserve human-readable allocation amounts.

* **Documentation**
  * Clarified amount conventions and updated migration guides.

* **Tests**
* Added unit tests for amount semantics and RPC wire/request-response
shapes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
ihsraham added a commit that referenced this pull request May 6, 2026
## Summary

Adds protocol, TS SDK, and compat SDK drift guards on top of current
`main`.

#699 and #701 are now merged, so this branch has been rebased directly
on `main` and preserves current behavior for:

- `nitronode` naming and paths
- #699 compat runtime semantics and migration surface
- #701 `appDefinition` mapping and SDK `applicationID` exports
- package versions at `1.2.1`

## Change Areas

### Drift Guards

- Adds static guards for RPC method coverage, RPC DTO shape, public API
snapshots, consumed ABI surface, app/session-key signing vectors, and
response transforms.
- Adds compat drift coverage for v1 app-session mapping, legacy flat
fallback behavior, empty-session behavior, asset decimal conversion,
config pass-through, and session-key public APIs.
- Adds runtime smoke coverage that builds and starts an isolated local
`nitronode`, then verifies live SDK and compat calls.

### SDK Validation

- Validates key-state `states` containers before mapping.
- Validates app-session payloads, allocations, app definitions,
participants, and quorum at the wire boundary.
- Rejects arrays in session key-state record transforms.

### Nitronode Database

- Propagates SQLite migration errors from `connectToSqlite`.
- Returns Postgres migration errors instead of panicking.
- Keeps SQLite auto-migration aligned with current runtime tables,
including state, transaction, app participants, and key-state tables.
- Uses a parameterized schema existence check and quoted schema
identifiers for Postgres schema setup.

### Runtime Smoke And CI

- Builds `./nitronode` and uses `NITRONODE_RUNTIME_SMOKE_*` env names in
new scripts/workflows/docs.
- Requires `NITRONODE_RUNTIME_SMOKE_PRIVATE_KEY` for external smoke
mode.
- Keeps the hardcoded Anvil key only for isolated local smoke.
- Restricts runtime-smoke log directories to repo-local paths.
- Passes an allowlisted child-process env instead of forwarding all
parent env.
- Captures compat logs for failure diagnostics.
- Builds Foundry artifacts before TS SDK/static drift ABI checks in CI.

## Review Notes

Addressed current actionable review feedback around SDK response
validation, database migration error handling, runtime-smoke env/log
safety, public API tautology tests, ABI drift-test stability, and stale
Clearnode wording in PR-added files.

Deferred CodeRabbit docstring coverage and shared public API test
utility extraction because they are broader cleanup items, not blockers
for this PR.

## Verification

Local checks run from a fresh worktree:

- `npm --prefix sdk/ts run typecheck`
- `npm --prefix sdk/ts test`
- `npm --prefix sdk/ts run lint`
- `npm --prefix sdk/ts run build:ci`
- `npm --prefix sdk/ts-compat run typecheck`
- `npm --prefix sdk/ts-compat test`
- `npm --prefix sdk/ts-compat run lint`
- `npm --prefix sdk/ts-compat run build:ci`
- `forge build` for local ABI artifacts
- `./scripts/check-protocol-drift.sh --static`
- `./scripts/check-protocol-drift.sh --runtime`
- `go test ./nitronode/... ./pkg/rpc/...`
- `git diff --check`

GitHub checks have started on the rebased branch.
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