Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
600301a
Add a versioned wallet UI-state cache file and Redux seeding action
j0ntz Jul 18, 2026
5105dcc
Emit currency wallets before their engines exist
j0ntz Jul 18, 2026
ed985f4
Add deterministic tests for the wallet UI-state cache
j0ntz Jul 18, 2026
c09ac2c
Schedule cached wallets' engine startup behind a limited-concurrency …
j0ntz Jul 19, 2026
0ad9cff
Keep the existing balanceMap when a balance report is unchanged
j0ntz Jul 19, 2026
4783de3
Add deterministic engine-scheduler tests
j0ntz Jul 19, 2026
ff930d2
Seed the account boot state from a local cache
j0ntz Jul 21, 2026
9d7718f
Drop the duplicate publicKey.json read in the queued engine block
j0ntz Jul 21, 2026
e849063
Add account-cache and bulk-seeding tests
j0ntz Jul 21, 2026
b89bb6c
Keep user changes over racing wallet file loads
j0ntz Jul 21, 2026
a857b19
Deliver account state to engines that start before it loads
j0ntz Jul 21, 2026
f4e14c5
Make storage sync wait for the storage wallet
j0ntz Jul 21, 2026
6e27cf5
Wait for builtin tokens before filtering enabled token ids
j0ntz Jul 21, 2026
5f3b860
Stop the deferred boot loads after a logout
j0ntz Jul 21, 2026
b4f6389
Reject a pending storage sync on logout or wallet deletion
j0ntz Jul 21, 2026
71beb97
Reject repo waiters after a terminal boot-load failure
j0ntz Jul 21, 2026
93ceb0c
Wait for plugin settings before writing them
j0ntz Jul 21, 2026
d7a0ed0
Reject a pending token toggle after a terminal boot failure
j0ntz Jul 21, 2026
dc1cb70
Wait for the wallet-state load before changing wallet states
j0ntz Jul 21, 2026
d8c48b2
Gate the account token saver on the custom-token load
j0ntz Jul 21, 2026
7a80922
Keep user token edits per token id when a load races them
j0ntz Jul 21, 2026
3bbc97f
Apply enabled-token changes as toggles over the loaded list
j0ntz Jul 21, 2026
e9027da
Track dirty plugin settings per plugin id
j0ntz Jul 21, 2026
987632c
Wait for the engine in the account-level engine methods
j0ntz Jul 21, 2026
9b4fe78
Watch currencyWalletIds in the account cache saver
j0ntz Jul 21, 2026
1e2d480
Accept hash-suffixed store routes in the fake sync server
j0ntz Jul 21, 2026
16ff1fe
Add write-path staleness tests
j0ntz Jul 21, 2026
2ea1c01
Serve cached addresses before the engine on stable-address chains
j0ntz Jul 22, 2026
e1f7c42
Expose otherMethods as permanent delegating stubs
j0ntz Jul 22, 2026
f5f0e64
Cache config otherMethod names
j0ntz Jul 22, 2026
b034623
Add address and otherMethods cache tests
j0ntz Jul 22, 2026
bb3a169
Key the address cache by tokenId and rebuild stubs on growth
j0ntz Jul 22, 2026
eeabe43
Keep the live plugin surface for config otherMethods
j0ntz Jul 22, 2026
bf2bf4b
Harden the boot-retry and scheduler-timeout edge paths
j0ntz Jul 22, 2026
e3fab42
Serialize repo syncs per storage wallet
j0ntz Jul 22, 2026
6f7c633
Add allowCached opt-in for provisional receive addresses
j0ntz Jul 23, 2026
c532ebe
Unwedge wallet pixies when the deferred account load fails
j0ntz Jul 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

- added: Per-wallet `walletCache.json` with each wallet's name, fiat code, enabled token IDs, and last-known balances. Currency wallets now emit their API objects as soon as this cache loads, before their engines exist, so the GUI can render the wallet list immediately at login. Engine-backed methods wait for the engine internally and reject if it fails or the wallet is deleted. First login (no cache) behaves exactly as before.
- changed: `waitForCurrencyWallet` and `waitForAllWallets` now resolve when the wallet object exists, which can be before its engine loads.
- changed: `wallet.otherMethods` is `{}` until the wallet's engine loads, then switches to the engine's methods.

## 2.47.1 (2026-07-17)

- fixed: Revert `@nymproject/mix-fetch` to v1 (1.4.4), restoring the pinned gateway and network requester. The v2 stack shipped in 2.47.0 fails to complete small HTTPS JSON-RPC requests through most exit nodes and its exit-node auto-discovery rarely converges, which left wallets with NYM privacy enabled unable to sync or send.
Expand Down
13 changes: 13 additions & 0 deletions src/core/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
EdgeBalanceMap,
EdgeCorePlugin,
EdgeCorePluginsInit,
EdgeCurrencyTools,
Expand Down Expand Up @@ -271,6 +272,18 @@ export type RootAction =
tools: Promise<EdgeCurrencyTools>
}
}
| {
// Called when the wallet's UI-state cache file loads from disk,
// seeding Redux before the engine exists.
type: 'CURRENCY_WALLET_CACHE_LOADED'
payload: {
balanceMap: EdgeBalanceMap
enabledTokenIds: string[]
fiatCurrencyCode: string
name: string | null
walletId: string
}
}
| {
type: 'CURRENCY_WALLET_CHANGED_PAUSED'
payload: {
Expand Down
24 changes: 16 additions & 8 deletions src/core/currency/currency-selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,28 @@ export function getCurrencyMultiplier(
return '1'
}

/**
* Throws if a wallet has been deleted mid-wait or its engine has failed,
* so `waitFor` conditions surface those as rejections instead of hangs.
*/
export function checkCurrencyWallet(props: RootProps, walletId: string): void {
// If the wallet id doesn't even exist, bail out:
if (props.state.currency.wallets[walletId] == null) {
throw new Error(`Wallet id ${walletId} does not exist in this account`)
}

// Throw the error if one exists:
const { engineFailure } = props.state.currency.wallets[walletId]
if (engineFailure != null) throw engineFailure
}

export function waitForCurrencyWallet(
ai: ApiInput,
walletId: string
): Promise<EdgeCurrencyWallet> {
const out: Promise<EdgeCurrencyWallet> = ai.waitFor(
(props: RootProps): EdgeCurrencyWallet | undefined => {
// If the wallet id doesn't even exist, bail out:
if (props.state.currency.wallets[walletId] == null) {
throw new Error(`Wallet id ${walletId} does not exist in this account`)
}

// Return the error if one exists:
const { engineFailure } = props.state.currency.wallets[walletId]
if (engineFailure != null) throw engineFailure
checkCurrencyWallet(props, walletId)

// Return the API if that exists:
if (props.output.currency.wallets[walletId] != null) {
Expand Down
Loading
Loading