Skip to content

feat(extension-wallet): wire session key TTL refresh to AccountContract - #1215

Open
OZILSOLAR wants to merge 1 commit into
ancore-org:mainfrom
OZILSOLAR:963-wire-session-keys-ui-refresh-ttl-to-account-contract
Open

feat(extension-wallet): wire session key TTL refresh to AccountContract#1215
OZILSOLAR wants to merge 1 commit into
ancore-org:mainfrom
OZILSOLAR:963-wire-session-keys-ui-refresh-ttl-to-account-contract

Conversation

@OZILSOLAR

Copy link
Copy Markdown

Wire Session Keys UI Refresh TTL to AccountContract / Core-SDK

Summary

This PR integrates real smart contract interaction for the session key TTL refresh functionality, resolving a critical security vulnerability where
users believed their session expiry was extended when only the frontend state was updated. The refreshSessionKey hook now properly calls the
@ancore/core-sdk's refreshSessionKeyTtl method to extend the Soroban persistent storage TTL on-chain.

Closes #963

Problem Statement

The useSessionKeys.refreshSessionKey hook was only modifying local UI state without actually calling the smart contract to refresh the session key TTL
on-chain. This created a false sense of security:

  • Users saw the new expiry time in the UI
  • But the Soroban storage TTL was never extended
  • The session key could be evicted from storage before the displayed expiry time
  • This is a critical security and UX issue

Solution

Core Changes

1. Contract Integration in useSessionKeys.ts

  • Integrated AncoreClient.refreshSessionKeyTtl() to actually invoke the smart contract
  • Implements optimistic UI update pattern with rollback on failure
  • Proper error handling and loading state management
  • Added authState.accountAddress to the dependency array for correct client initialization

2. Implementation Flow

Optimistically update local state (instant UI feedback)

Create AncoreClient with account contract ID

Call client.refreshSessionKeyTtl(publicKey, expiresAt)

Success: Contract extends Soroban TTL, UI shows new expiry

Failure: Rollback local state, display error message

3. Comprehensive Test Suite

Created useSessionKeys.test.ts with 10+ test cases covering:

  • Initial state verification
  • Optimistic UI updates
  • Contract method invocation with correct parameters
  • Loading state transitions
  • Rollback behavior on contract errors
  • Error message handling
  • Session key validation (not found scenario)
  • AncoreClient proper initialization
  • Error clearing functionality

Key Features

Security

✅ Eliminates false security by ensuring actual on-chain state changes
✅ Proper validation of session key existence before contract call
✅ Error handling prevents misleading UI states

User Experience

✅ Optimistic UI updates provide instant feedback
✅ Loading state indicates ongoing contract operation
✅ Clear error messages on failures
✅ Automatic rollback prevents inconsistent UI/contract states

Code Quality

✅ Follows existing patterns in addSessionKey and revokeSessionKey
✅ Proper dependency management in useCallback
✅ Comprehensive test coverage
✅ Clear error handling with user-friendly messages

Files Changed

Modified

  • apps/extension-wallet/src/hooks/useSessionKeys.ts
    • Updated refreshSessionKey callback to call client.refreshSessionKeyTtl()
    • Added loading state management with setIsLoading(true/false)
    • Implemented rollback mechanism on contract failure
    • Added authState.accountAddress to dependency array
    • Lines changed: +13, -3

Added

  • apps/extension-wallet/src/hooks/__tests__/useSessionKeys.test.ts (NEW)
    • Comprehensive test suite with 10+ test cases
    • Mocked dependencies (AuthGuard, sessionKeysStore, coreSdk)
    • Tests for success paths, error paths, and edge cases
    • Lines added: 238

Technical Details

Contract Method Signature

client.refreshSessionKeyTtl({
  publicKey: string;        // Session key to refresh
  expiresAt: number;        // Original session key expiry (Unix seconds)
}): InvocationArgs

Parameter Semantics

- publicKey: The Ed25519 public key (G…) of the session key
- expiresAt: The known logical expiry from local state (used for validation only)
- The contract extends Soroban persistent storage TTL to prevent key eviction
- The contract does NOT change the logical expiresAt value (set via addSessionKey)

Error Handling

- Validation Errors: BuilderValidationError if parameters are invalid
- Session Key Expired: SessionKeyManagementError if key has expired
- Contract Errors: Mapped to SessionKeyManagementError with appropriate codes
- Generic Errors: Wrapped as SESSION_KEY_TTL_REFRESH_FAILED

Testing

Test Coverage

-  Initial state verification
-  Optimistic update behavior
-  Contract method invocation with correct parameters
-  Loading state management during operation
-  Rollback on contract failure
-  Error message handling
-  Session key not found validation
-  Error clearing functionality
-  AncoreClient initialization
-  Proper dependency injection

Test Execution

Tests use Vitest with mocked dependencies:
- @/router/AuthGuard - Mock authentication state
- @/stores/sessionKeys - Mock session key storage
- @ancore/core-sdk - Mock AncoreClient and contract operations

Migration Notes

Backward Compatibility

 Fully backward compatible - same function signature and return type
 Existing code using this hook requires no changes
 Behavior improves without breaking changes

Dependencies

- No new dependencies added
- Uses existing @ancore/core-sdk functionality
- Compatible with current wallet architecture

Validation Checklist

-  Code follows existing patterns in the codebase
-  Error handling covers all failure scenarios
-  Loading states provide user feedback
-  Optimistic updates improve perceived performance
-  Rollback ensures data consistency
-  Tests cover success and failure paths
-  No breaking changes introduced
-  Resolves the security vulnerability from #963

Related Issues

- Closes #963: [EXTENSION] Wire Session Keys UI refresh TTL to AccountContract / core-sdk

Integrate real contract interaction for refreshSessionKey hook (ancore-org#963)

- Implement contract call to refreshSessionKeyTtl via AncoreClient
- Maintain optimistic UI update with rollback on contract failure
- Add proper loading state during contract interaction
- Pass original session key expiresAt to contract for TTL extension
- Add comprehensive test coverage for refresh functionality

The refreshSessionKey hook now:
1. Optimistically updates local state with new expiry time
2. Calls client.refreshSessionKeyTtl() to extend Soroban TTL on-chain
3. Rolls back local changes if contract operation fails
4. Handles loading states and error messages properly

This resolves the security vulnerability where users believed their
session expiry was extended when only the frontend store was updated.
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4d3241f2-86aa-4914-8e7d-8e6b4f17b78d


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.

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.

[EXTENSION] Wire Session Keys UI refresh TTL to AccountContract / core-sdk

1 participant