refactor: replace WASM dependency in SessionProvider with pure TypeScript#2542
Open
kronosapiens wants to merge 22 commits into
Open
refactor: replace WASM dependency in SessionProvider with pure TypeScript#2542kronosapiens wants to merge 22 commits into
kronosapiens wants to merge 22 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
e4f1996 to
000d731
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2542 +/- ##
==========================================
- Coverage 21.41% 21.30% -0.11%
==========================================
Files 339 342 +3
Lines 37969 38436 +467
Branches 1216 1224 +8
==========================================
+ Hits 8131 8190 +59
- Misses 29819 30227 +408
Partials 19 19 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
8607308 to
180c87f
Compare
Contributor
Author
|
Confirming that this code has been manually exercised using the Capacitor example in |
…ript Replace @cartridge/controller-wasm imports in session/node paths with pure TS implementations using only starknet.js primitives, enabling React Native support and simplifying the build pipeline. Adds 45 new tests covering guid derivation, merkle tree construction, outside execution signing, session account operations, and GraphQL subscription polling. Closes #2518 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The class has identical behavior to the WASM original and the original name never implied a WASM implementation, so keep the established name. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on.ts to execution.ts The session/ts/ directory already establishes context, making the prefixes redundant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Small single-function module absorbed into existing utilities file. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The "ts" name was meaningless — everything is TypeScript. "internal" clearly signals these are implementation details behind the session API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
node/ was reaching into session/internal/ directly. Re-export CartridgeSessionAccount and signerToGuid from session/index.ts so node/ imports from ../session instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drop JsFelt (inline string), rename JsCall to SessionCall, remove unused JsOutsideExecutionV3 and JsSignedOutsideExecution. The Js prefixes were WASM artifacts with no meaning in pure TypeScript. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Felt communicates domain intent better than raw string. Renamed from JsFelt to Felt since the Js prefix was a WASM artifact. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove broken CartridgeSessionAccount.execute() that used an outside-execution signature for a regular invoke transaction - Add isSnip9CompatibilityError() (ported from reference) so callers can distinguish SNIP-9 incompatibility from real failures - Replace catch-all fallback in session/account.ts and node/account.ts with selective SNIP-9 detection; non-SNIP-9 errors now propagate immediately instead of being swallowed - Fix localeCompare sorting in toWasmPolicies to use pure byte-order comparison, matching the reference and eliminating locale-dependent merkle root differences - Add executeBefore > executeAfter validation in buildSignedOutsideExecutionV3 - Add test coverage: time-bound validation, isSnip9CompatibilityError, error propagation, and locale-independent address sorting Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add tests for normalizeFelt, selectorFromEntrypoint, and normalizeContractAddress. Add multi-call test for buildSignedOutsideExecutionV3 to exercise calldata serialization across multiple calls with different lengths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TypedDataPolicy was using the CallPolicy type hash ("Allowed Method")
instead of its own ("Allowed Type"). ApprovalPolicy was hashing all
three fields (target, spender, amount) instead of converting to
CallPolicy(target, approve_selector) as the WASM boundary does.
Also fixes the proof index selector for ApprovalPolicy.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Explains that the fallback is blocked by Cartridge's guardian co-signing policy, not by a protocol limitation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- hashPolicyLeaf returns 0x0 for unauthorized policies (matching WASM) - subscribeCreateSession throws immediately on GraphQL errors instead of retrying, adds per-request AbortController timeout - Rename misleading execute() test to clarify it tests the internal CartridgeSessionAccount class Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove 23 tests that were subsumed by stronger tests, tested starknet.js rather than our code, or exercised the same branch at different scale. 134 → 111 total. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The capacitor:// origin is not allowed by the RPC server's CORS policy, causing fetch requests to fail in the native WebView. CapacitorHttp routes requests through the native HTTP layer instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…oller package The session provider now uses pure TypeScript — no WASM imports remain in packages/controller/src/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
Closes #2518
This PR integrates the TS implementation of the SessionProvider from StarkZap, dropping the WASM dependency from
controller-rsand unlocking React Native integration.Summary
@cartridge/controller-wasmimports in the session/node paths with pure TypeScript implementations using onlystarknet.jsprimitivespackages/controller/src/session/internal/implementing signerToGuid, Poseidon merkle trees, SNIP-9 v2 outside execution signing, session token serialization, and GraphQL subscription pollingsession/provider.ts,session/account.ts,session/index.ts,node/provider.ts,node/account.ts,utils.ts) — no public API changeslocaleComparewith byte-order string comparison intoWasmPoliciesto ensure deterministic policy sorting across locales@cartridge/controller-wasmas a dependency inpackage/controllerBenefits
vite-plugin-wasm/vite-plugin-top-level-await.{"code":131}). The TS version gives readable stack traces and can be debugged with aconsole.logand a rebuild. Every developer who hits a session issue benefits.@cartridge/controller-wasm@0.10.0). Fixing a session signing bug currently requires: fix in Rust → build WASM → publish package → bump version in controller → release. With TS it's one PR.Key files
New files under
packages/controller/src/session/internal/(93% statement / 94% line coverage):execution.tsmerkle.tsutils.tssignerToGuid(Poseidon hash of domain + public key).account.tsCartridgeSessionAccount— holds session credentials and submits signed payloads to the Cartridge RPC viacartridge_addExecuteOutsideTransaction.subscribe.tserrors.tsSessionProtocolError,SessionTimeoutError, and SNIP-9 compatibility detection.types.tsCallPolicy,TypedDataPolicy,ApprovalPolicy,Session.Notes
Decoupling from controller-rs
This creates a second implementation of session signing alongside
controller-rs, which is still consumed by the keychain. The two implementations both conform to the same on-chain session protocol (SNIP-9 v2 + Cartridge session token format). Correctness is enforced by the contract at submission time — if either implementation produces a malformed payload, it is rejected by the RPC. If the protocol changes, both implementations will need to be updated.Behavioral change:
execute()fallback removedThe old code silently fell back to
this.controller.execute()(direct invocation) whenexecuteFromOutside()failed. This fallback could never succeed under Cartridge's current session registration flow (due to required guardian signature replacement), so the new code throws aSessionProtocolErrorwith a clear message instead.References
Test plan
pnpm build)pnpm lint)executeFromOutsideproduces payloads accepted by Cartridge relayer🤖 Generated with Claude Code