Skip to content

Comments

Cache and restore wallets#703

Open
paullinator wants to merge 2 commits intomasterfrom
paul/cacheWallets
Open

Cache and restore wallets#703
paullinator wants to merge 2 commits intomasterfrom
paul/cacheWallets

Conversation

@paullinator
Copy link
Member

@paullinator paullinator commented Feb 4, 2026

Improve login performance by caching wallet state on a per account level in unencrypted JSON file and rehydrate before wallets load.

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

none

Note

Medium Risk
Touches the login/account lifecycle and wallet/config object behavior, including async delegation and disk persistence; mistakes could cause stale UI state, extra disk writes, or login regressions despite strong test coverage.

Overview
Adds a cache-first login path that saves wallet/config state to accountCache/<storageWalletId>/walletCache.json and, on subsequent logins, restores lightweight EdgeCurrencyWallet/EdgeCurrencyConfig objects so the app can render wallets before currency engines finish loading.

Introduces new cache modules (cache-wallet-saver, cache-wallet-loader, cached wallet/config wrappers, shared poller + otherMethods/disklet delegation) and wires them into account-pixie (load cache early, background file loading, throttled reactive auto-save) and account-api (merge cached + real wallets/IDs until keysLoaded). Adds extensive end-to-end tests plus fake plugin controls to deterministically gate engine creation and validate delegation/yaob update propagation; also improves swap quote cleanup logging and exports asEdgeToken for cache validation.

Written by Cursor Bugbot for commit 3e6460c. This will update automatically on new commits. Configure here.


@cursor

This comment has been minimized.

@cursor

This comment has been minimized.

@cursor

This comment has been minimized.

@paullinator paullinator force-pushed the paul/cacheWallets branch 3 times, most recently from db35d1c to 38a0e8c Compare February 19, 2026 00:08
@cursor

This comment has been minimized.

@cursor

This comment has been minimized.

@paullinator paullinator force-pushed the paul/cacheWallets branch 3 times, most recently from 294dc9f to e82fdcd Compare February 19, 2026 13:27
@cursor

This comment has been minimized.

Add missing return in fake plugin getBalance for token balance.
Improve @ts-expect-error comment and log swap quote close errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
}
const errorWithCode = error as Error & { code?: string }
return errorWithCode.code === 'ENOENT'
}
Copy link

Choose a reason for hiding this comment

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

File-not-found detection is too fragile

Low Severity

isFileNotFoundError depends on exact, case-sensitive Error.message prefixes ('Cannot load', 'Cannot read file') to detect missing cache files. If disklet changes wording/casing or platform-specific messages differ, first-login “missing cache” can be misclassified as unexpected and logged as a warning.

Fix in Cursor Fix in Web

@cursor

This comment has been minimized.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is ON. A Cloud Agent has been kicked off to fix the reported issues.

get userSettings(): object | undefined {
const realConfig = tryGetRealConfig()
return realConfig != null ? realConfig.userSettings : {}
},
Copy link

Choose a reason for hiding this comment

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

Cached config returns empty userSettings

Medium Severity

The cached EdgeCurrencyConfig.userSettings getter returns {} when the real config is unavailable, even though the type is object | undefined. This changes semantics for callers that distinguish “no settings yet” (undefined) from “settings exist” (object), and can cause cache-mode behavior to diverge from real-config behavior.

Fix in Cursor Fix in Web

// Data store:
get created(): Date | undefined {
return createdDate
},
Copy link

Choose a reason for hiding this comment

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

Cached wallet created date may be invalid

Low Severity

makeCachedCurrencyWallet converts cacheData.created to createdDate = new Date(createdString) and always returns it from created. If the cache has an invalid or non-ISO created string, created becomes an “Invalid Date” object instead of undefined, which can break consumers that assume a valid Date.

Fix in Cursor Fix in Web

@cursor
Copy link

cursor bot commented Feb 23, 2026

Bugbot Autofix prepared fixes for 2 of the 2 bugs found in the latest run.

  • ✅ Fixed: Cached config returns empty userSettings
    • Changed the userSettings getter to return undefined instead of {} when the real config is unavailable, preserving the semantic distinction between 'no settings' and 'settings exist'.
  • ✅ Fixed: Cached wallet created date may be invalid
    • Added validation to check if the parsed date is valid using isNaN(parsedDate.getTime()), returning undefined for invalid date strings instead of an Invalid Date object.

Create PR

Or push these changes by commenting:

@cursor push e6e1588d29
Preview (e6e1588d29)
diff --git a/src/core/cache/cached-currency-config.ts b/src/core/cache/cached-currency-config.ts
--- a/src/core/cache/cached-currency-config.ts
+++ b/src/core/cache/cached-currency-config.ts
@@ -141,7 +141,7 @@
     // User settings (delegate when available, write delegates):
     get userSettings(): object | undefined {
       const realConfig = tryGetRealConfig()
-      return realConfig != null ? realConfig.userSettings : {}
+      return realConfig != null ? realConfig.userSettings : undefined
     },
 
     async changeUserSettings(settings: object): Promise<void> {

diff --git a/src/core/cache/cached-currency-wallet.ts b/src/core/cache/cached-currency-wallet.ts
--- a/src/core/cache/cached-currency-wallet.ts
+++ b/src/core/cache/cached-currency-wallet.ts
@@ -155,7 +155,8 @@
   } = cacheData
 
   const shortId = walletId.slice(0, WALLET_ID_DISPLAY_LENGTH)
-  const createdDate = new Date(createdString)
+  const parsedDate = new Date(createdString)
+  const createdDate = isNaN(parsedDate.getTime()) ? undefined : parsedDate
 
   // Track mutable state locally. When the GUI calls a setter, we update
   // the local value immediately and call update(wallet) to push it

@paullinator
Copy link
Member Author

/rebase

Improve login performance by caching wallet state on a per account level in unencrypted JSON file and rehydrate before wallets load.
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.

1 participant