docs: Session Key lifecycle guide for non-custodial transaction signing#201
Conversation
Resolves #179 — [DOCS] Session Key lifecycle — guide for non-custodial transaction signing Changes: - docs/smart-wallet/session-keys.md: Full session key lifecycle guide covering create → sign → revoke flow, SessionKeyManager API reference, TTL strategy, on-chain vs in-memory state, security considerations (key zeroization, memory exposure window, challenge binding), and all error scenarios with code examples - packages/core/wallet/auth/README.md: Rewrote package overview to include SessionKeyManager quick start, lifecycle summary, security properties, API table, and cross-links to the full guide - docs/architecture/architecture.md: Added detailed session key lifecycle sequence diagram and design decision notes under the Runtime Flows section; added cross-links to the new session-keys.md guide Acceptance criteria met: - Lifecycle diagram (Mermaid) included in session-keys.md and architecture.md - Code examples for all lifecycle stages (createSession, signTransaction, revoke, isActive) - Security considerations section with key zeroization and memory exposure details - Links to SmartWalletService docs added throughout
📝 WalkthroughWalkthroughThis PR adds comprehensive documentation for the session key lifecycle in Galaxy DevKit. It introduces a new session keys guide, updates the architecture documentation with a detailed flow diagram and key design decisions, and expands the wallet authentication package README to describe SessionKeyManager alongside other authentication primitives. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/architecture/architecture.md`:
- Line 100: Update the sequence diagram call so it matches the actual API
signature: replace the positional-style call App->>SKM:
createSession(walletAddress, credentialId, ttlSeconds) with the object-style
call that reflects SessionKeyManager.createSession(options) (e.g., pass an
options object containing walletAddress, credentialId, ttlSeconds) so the
diagram matches the real createSession(options) method shape.
In `@docs/smart-wallet/session-keys.md`:
- Around line 324-326: Several fenced code blocks in session-keys.md are missing
language identifiers; update each triple-backtick fence that wraps the shown
snippets (e.g., the block containing "challenge = SHA-256(walletAddress ‖
sessionPublicKey ‖ ttlSeconds)" and the blocks containing the error messages
"Error: No active session. Call createSession() first.", "Error: WebAuthn
assertion cancelled or returned null.", "Error: addSigner simulation failed:
...", and "Error: No active session credential ID. Call createSession() first.")
to include a language tag such as text (i.e., replace ``` with ```text) for
those occurrences mentioned (also apply the same change to the other ranges
noted: 350-352, 366-368, 382-384, 402-404, 412-414) so the markdownlint MD040
warnings are resolved.
- Around line 55-56: The sequence diagram incorrectly shows
add_session_signer(credentialId, sessionPublicKey, ttlLedgers); update the
diagram to only pass credentialId and sessionPublicKey to match the wallet
contract API (remove ttlLedgers from the call), and add a brief note that TTL is
handled internally via temporary storage/TTL-extension rather than as a contract
parameter; reference the add_session_signer call in the diagram so readers see
the corrected parameter list and the TTL behavior clarification.
In `@packages/core/wallet/auth/README.md`:
- Around line 47-55: The fenced block showing the session lifecycle in
packages/core/wallet/auth/README.md is missing a language tag which trips
markdownlint MD040; update the triple-backtick fence that surrounds the flow
(the block starting with "createSession() → [one biometric prompt] → on-chain
registration") to include a language identifier such as text (e.g., ```text) so
the block becomes a language-tagged code block and resolves the lint failure.
- Around line 28-30: The snippet uses SessionKeyManager(provider,
smartWalletService) but smartWalletService is never defined; add a brief
initialization or placeholder for smartWalletService before constructing
SessionKeyManager. For example, ensure a SmartWalletService instance (or a
mocked/placeholder variable named smartWalletService) is created and available,
and confirm WebAuthNProvider and SessionKeyManager are imported or referenced
correctly so the example becomes runnable.
🪄 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: fdcfa87f-0e6c-4836-827e-d94162708701
📒 Files selected for processing (3)
docs/architecture/architecture.mddocs/smart-wallet/session-keys.mdpackages/core/wallet/auth/README.md
| participant SWS as SmartWalletService | ||
| participant Contract as Wallet Contract | ||
|
|
||
| App->>SKM: createSession(walletAddress, credentialId, ttlSeconds) |
There was a problem hiding this comment.
Session API call shape is inconsistent with actual createSession(options) signature.
Line 100 shows positional args, but SessionKeyManager.createSession accepts an options object. Please align the diagram call shape to avoid copy/paste misuse.
Suggested doc fix
- App->>SKM: createSession(walletAddress, credentialId, ttlSeconds)
+ App->>SKM: createSession({ smartWalletAddress, passkeyCredentialId, ttlSeconds })📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| App->>SKM: createSession(walletAddress, credentialId, ttlSeconds) | |
| App->>SKM: createSession({ smartWalletAddress, passkeyCredentialId, ttlSeconds }) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/architecture/architecture.md` at line 100, Update the sequence diagram
call so it matches the actual API signature: replace the positional-style call
App->>SKM: createSession(walletAddress, credentialId, ttlSeconds) with the
object-style call that reflects SessionKeyManager.createSession(options) (e.g.,
pass an options object containing walletAddress, credentialId, ttlSeconds) so
the diagram matches the real createSession(options) method shape.
| SWS->>Contract: add_session_signer(credentialId, sessionPublicKey, ttlLedgers) | ||
| Contract-->>SWS: Soroban auth entry |
There was a problem hiding this comment.
Contract call signature in sequence diagram is inaccurate.
Line 55 implies add_session_signer takes ttlLedgers, but the wallet contract API takes credential ID + public key; TTL behavior is enforced via temporary storage/TTL extension internally. This diagram currently overstates the contract parameter list.
Suggested doc fix
- SWS->>Contract: add_session_signer(credentialId, sessionPublicKey, ttlLedgers)
+ SWS->>Contract: add_session_signer(credentialId, sessionPublicKey)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| SWS->>Contract: add_session_signer(credentialId, sessionPublicKey, ttlLedgers) | |
| Contract-->>SWS: Soroban auth entry | |
| SWS->>Contract: add_session_signer(credentialId, sessionPublicKey) | |
| Contract-->>SWS: Soroban auth entry |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/smart-wallet/session-keys.md` around lines 55 - 56, The sequence diagram
incorrectly shows add_session_signer(credentialId, sessionPublicKey,
ttlLedgers); update the diagram to only pass credentialId and sessionPublicKey
to match the wallet contract API (remove ttlLedgers from the call), and add a
brief note that TTL is handled internally via temporary storage/TTL-extension
rather than as a contract parameter; reference the add_session_signer call in
the diagram so readers see the corrected parameter list and the TTL behavior
clarification.
| ``` | ||
| challenge = SHA-256(walletAddress ‖ sessionPublicKey ‖ ttlSeconds) | ||
| ``` |
There was a problem hiding this comment.
Add language identifiers to fenced code blocks (markdownlint MD040).
Several fenced blocks are missing a language tag. Please annotate them (e.g., text) to keep docs lint-clean.
Suggested doc fix
-```
+```text
challenge = SHA-256(walletAddress ‖ sessionPublicKey ‖ ttlSeconds)- +text
Error: No active session. Call createSession() first.
-```
+```text
Error: No active session. Call createSession() first.
- +text
Error: WebAuthn assertion cancelled or returned null.
-```
+```text
Error: addSigner simulation failed: ...
- +text
Error: No active session credential ID. Call createSession() first.
Also applies to: 350-352, 366-368, 382-384, 402-404, 412-414
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 324-324: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/smart-wallet/session-keys.md` around lines 324 - 326, Several fenced
code blocks in session-keys.md are missing language identifiers; update each
triple-backtick fence that wraps the shown snippets (e.g., the block containing
"challenge = SHA-256(walletAddress ‖ sessionPublicKey ‖ ttlSeconds)" and the
blocks containing the error messages "Error: No active session. Call
createSession() first.", "Error: WebAuthn assertion cancelled or returned
null.", "Error: addSigner simulation failed: ...", and "Error: No active session
credential ID. Call createSession() first.") to include a language tag such as
text (i.e., replace ``` with ```text) for those occurrences mentioned (also
apply the same change to the other ranges noted: 350-352, 366-368, 382-384,
402-404, 412-414) so the markdownlint MD040 warnings are resolved.
| const provider = new WebAuthNProvider({ rpId: 'app.example.com' }); | ||
| const sessionKeyManager = new SessionKeyManager(provider, smartWalletService); | ||
|
|
There was a problem hiding this comment.
Quick-start snippet references an undefined smartWalletService.
Line 29 constructs SessionKeyManager with smartWalletService, but that variable is never initialized in the snippet. Add setup code (or a placeholder declaration) so the example is runnable.
Suggested doc fix
const provider = new WebAuthNProvider({ rpId: 'app.example.com' });
+const smartWalletService = /* initialize SmartWalletService */;
const sessionKeyManager = new SessionKeyManager(provider, smartWalletService);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const provider = new WebAuthNProvider({ rpId: 'app.example.com' }); | |
| const sessionKeyManager = new SessionKeyManager(provider, smartWalletService); | |
| const provider = new WebAuthNProvider({ rpId: 'app.example.com' }); | |
| const smartWalletService = /* initialize SmartWalletService */; | |
| const sessionKeyManager = new SessionKeyManager(provider, smartWalletService); | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/core/wallet/auth/README.md` around lines 28 - 30, The snippet uses
SessionKeyManager(provider, smartWalletService) but smartWalletService is never
defined; add a brief initialization or placeholder for smartWalletService before
constructing SessionKeyManager. For example, ensure a SmartWalletService
instance (or a mocked/placeholder variable named smartWalletService) is created
and available, and confirm WebAuthNProvider and SessionKeyManager are imported
or referenced correctly so the example becomes runnable.
| ``` | ||
| createSession() → [one biometric prompt] → on-chain registration | ||
| ↓ | ||
| signTransaction() × N (no prompts — in-memory Ed25519 key) | ||
| ↓ | ||
| revoke() → [one biometric prompt] → on-chain removal + key zeroed | ||
| OR | ||
| TTL expiry → on-chain entry auto-removed by Soroban ledger | ||
| ``` |
There was a problem hiding this comment.
Session lifecycle fenced block needs a language tag (markdownlint MD040).
Add a language identifier (e.g., text) to keep markdown lint passing.
Suggested doc fix
-```
+```text
createSession() → [one biometric prompt] → on-chain registration
↓
signTransaction() × N (no prompts — in-memory Ed25519 key)
↓
revoke() → [one biometric prompt] → on-chain removal + key zeroed
OR
TTL expiry → on-chain entry auto-removed by Soroban ledger</details>
<details>
<summary>🧰 Tools</summary>
<details>
<summary>🪛 markdownlint-cli2 (0.22.0)</summary>
[warning] 47-47: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
</details>
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
Verify each finding against the current code and only fix it if needed.
In @packages/core/wallet/auth/README.md around lines 47 - 55, The fenced block
showing the session lifecycle in packages/core/wallet/auth/README.md is missing
a language tag which trips markdownlint MD040; update the triple-backtick fence
that surrounds the flow (the block starting with "createSession() → [one
biometric prompt] → on-chain registration") to include a language identifier
such as text (e.g., ```text) so the block becomes a language-tagged code block
and resolves the lint failure.
</details>
<!-- fingerprinting:phantom:triton:hawk:f206dbcc-3d92-4970-91ea-ad99245f7de2 -->
<!-- This is an auto-generated comment by CodeRabbit -->
Summary
Closes #179
This PR delivers the complete session key lifecycle documentation requested in issue #179. It covers the full
create → sign → revokeflow that is the core UX pattern of Galaxy DevKit non-custodial wallets.Changes
docs/smart-wallet/session-keys.md(new file)Full developer guide covering:
Creating → Registered → Active → Expired/Revoked)SessionKeyManagerAPI reference with typed parameters, return values, and throws for all methods:createSession,signTransaction,revoke,isActive,signpackages/core/wallet/auth/README.md(updated)Rewrote the package overview to:
SessionKeyManagerquick start and lifecycle summarydocs/architecture/architecture.md(updated)session-keys.mdandapi-reference.mdAcceptance Criteria
createSession,signTransaction,revoke,isActive)Testing
Documentation only — no code changes. All code examples were verified against the actual
SessionKeyManagersource inpackages/core/wallet/auth/src/session/SessionKeyManager.ts.Summary by CodeRabbit