Skip to content

docs: Session Key lifecycle guide for non-custodial transaction signing#201

Merged
KevinMB0220 merged 1 commit intoGalaxy-KJ:mainfrom
JamesVictor-O:docs/session-key-lifecycle-guide
Mar 29, 2026
Merged

docs: Session Key lifecycle guide for non-custodial transaction signing#201
KevinMB0220 merged 1 commit intoGalaxy-KJ:mainfrom
JamesVictor-O:docs/session-key-lifecycle-guide

Conversation

@JamesVictor-O
Copy link
Copy Markdown
Contributor

@JamesVictor-O JamesVictor-O commented Mar 29, 2026

Summary

Closes #179

This PR delivers the complete session key lifecycle documentation requested in issue #179. It covers the full create → sign → revoke flow 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:

  • What session keys are and why they exist (single biometric prompt per session UX)
  • Lifecycle state diagram (Creating → Registered → Active → Expired/Revoked)
  • Detailed end-to-end sequence diagram (App → SessionKeyManager → WebAuthn → SmartWalletService → Contract)
  • SessionKeyManager API reference with typed parameters, return values, and throws for all methods: createSession, signTransaction, revoke, isActive, sign
  • TTL strategy — short / medium / long TTL guidance with rationale and code examples
  • On-chain vs in-memory state table (what lives where and for how long)
  • Security considerations: key zeroization, memory exposure window, challenge binding, no-persistent-storage contract
  • All error scenarios with messages and resolution steps
  • Full end-to-end integration example

packages/core/wallet/auth/README.md (updated)

Rewrote the package overview to:

  • Lead with SessionKeyManager quick start and lifecycle summary
  • Document key security properties
  • Provide an API method table
  • Cross-link to the full guide and related docs

docs/architecture/architecture.md (updated)

  • Added a detailed session key lifecycle sequence diagram under Current Runtime Flows
  • Added design decision notes (temporary storage, key zeroization order, challenge binding)
  • Added cross-links to session-keys.md and api-reference.md

Acceptance Criteria

  • Documentation is clear and comprehensive
  • Lifecycle diagram (Mermaid) included — state diagram + sequence diagram
  • Code examples for all lifecycle stages (createSession, signTransaction, revoke, isActive)
  • Security considerations section included (key zeroization, memory exposure window, challenge binding, no persistent storage)
  • Links to SmartWalletService docs added throughout

Testing

Documentation only — no code changes. All code examples were verified against the actual SessionKeyManager source in packages/core/wallet/auth/src/session/SessionKeyManager.ts.

Summary by CodeRabbit

  • Documentation
    • Added comprehensive session key lifecycle guide covering setup, transaction signing, and revocation.
    • Enhanced architecture documentation with sequence diagrams and key design decisions for session key management.
    • Expanded authentication documentation to cover multiple authentication primitives including session keys and updated integration flows.

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
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
Architecture Documentation
docs/architecture/architecture.md
Updated "Session Key Lifecycle" section with Mermaid sequence diagram showing flow across SessionKeyManager, WebAuthn, SmartWalletService, and wallet contract; added "Key design decisions" bullets covering in-memory private key storage, TTL-driven expiry, deterministic challenge binding, and pre-network zeroization; appended related documentation links.
Session Keys Guide
docs/smart-wallet/session-keys.md
New comprehensive guide defining session keys as short-lived Ed25519 delegate signers, detailing the full lifecycle (create → register on-chain → sign transactions → revoke/expire), SessionKeyManager API reference for all methods with error cases, TTL strategy guidance, on-chain vs in-memory state behavior, zeroization expectations, and a complete integration code example.
Wallet Authentication Package README
packages/core/wallet/auth/README.md
Reframed from narrow WebAuthn focus to broader authentication primitives; added "Packages at a Glance" module table; expanded SessionKeyManager documentation with lifecycle details, API summary, and security properties; updated smart wallet auth flow descriptions for admin vs session key signing; enhanced environment and testing sections; added "Related Docs" section with multiple links.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • KevinMB0220

Poem

🐰 A rabbit hops through docs so bright,
Session keys dancing in the light,
Diagrams flow from state to state,
Biometrics once, then sign away!
Keys zero out before they fade,
What developer dreams we've made! 🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main deliverable: a comprehensive session key lifecycle guide for non-custodial transaction signing, which directly matches the core changes in the PR.
Description check ✅ Passed The description is comprehensive and well-structured, covering all key sections: a clear summary, detailed change breakdown, acceptance criteria checklist, and testing notes. It follows the template structure effectively.
Linked Issues check ✅ Passed The PR fully addresses all coding/documentation requirements from issue #179: session key lifecycle explanation, state/sequence diagrams, SessionKeyManager API reference, TTL strategy, on-chain vs in-memory state, security considerations, error scenarios, and all required file updates.
Out of Scope Changes check ✅ Passed All changes are tightly scoped to the session key documentation objectives. The three files updated (session-keys.md new file, auth/README.md, and architecture.md) are all directly required by issue #179 with no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 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

📥 Commits

Reviewing files that changed from the base of the PR and between cc968c0 and 3f3a4ac.

📒 Files selected for processing (3)
  • docs/architecture/architecture.md
  • docs/smart-wallet/session-keys.md
  • packages/core/wallet/auth/README.md

participant SWS as SmartWalletService
participant Contract as Wallet Contract

App->>SKM: createSession(walletAddress, credentialId, ttlSeconds)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
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.

Comment on lines +55 to +56
SWS->>Contract: add_session_signer(credentialId, sessionPublicKey, ttlLedgers)
Contract-->>SWS: Soroban auth entry
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
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.

Comment on lines +324 to +326
```
challenge = SHA-256(walletAddress ‖ sessionPublicKey ‖ ttlSeconds)
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Comment on lines +28 to +30
const provider = new WebAuthNProvider({ rpId: 'app.example.com' });
const sessionKeyManager = new SessionKeyManager(provider, smartWalletService);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
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.

Comment on lines +47 to +55
```
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
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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 -->

@KevinMB0220 KevinMB0220 merged commit 5e04614 into Galaxy-KJ:main Mar 29, 2026
7 checks passed
@KevinMB0220 KevinMB0220 self-requested a review March 29, 2026 18:07
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.

[DOCS] Session Key lifecycle — guide for non-custodial transaction signing

2 participants