diff --git a/extension/popup/screens/HomeScreen.tsx b/extension/popup/screens/HomeScreen.tsx index 8f8c173..5916d31 100644 --- a/extension/popup/screens/HomeScreen.tsx +++ b/extension/popup/screens/HomeScreen.tsx @@ -270,9 +270,9 @@ export function HomeScreen() { } }; - // Filter to show outgoing and incoming transactions (exclude 'self' which is internal transfers) + // Only show outgoing transactions in history (we don't store incoming) const displayTransactions = walletTransactions.filter( - tx => tx.direction === 'outgoing' || tx.direction === 'incoming' + tx => tx.direction === 'outgoing' ); // Group wallet transactions by date diff --git a/extension/shared/vault.ts b/extension/shared/vault.ts index 9c693dd..a254063 100644 --- a/extension/shared/vault.ts +++ b/extension/shared/vault.ts @@ -497,9 +497,13 @@ export class Vault { > { const stored = await chrome.storage.local.get([ STORAGE_KEYS.ENCRYPTED_VAULT, + STORAGE_KEYS.ENCRYPTED_ACCOUNT_DATA, STORAGE_KEYS.CURRENT_ACCOUNT_INDEX, ]); const enc = stored[STORAGE_KEYS.ENCRYPTED_VAULT] as EncryptedVault | undefined; + const encAccountData = stored[STORAGE_KEYS.ENCRYPTED_ACCOUNT_DATA] as + | EncryptedAccountDataBlob + | undefined; const currentAccountIndex = (stored[STORAGE_KEYS.CURRENT_ACCOUNT_INDEX] as number | undefined) || 0; @@ -520,8 +524,35 @@ export class Vault { const payload = JSON.parse(pt) as VaultPayload; const accounts = payload.accounts; + // Load account data (same as password unlock) so transaction history displays + let utxoStore: UTXOStore = {}; + let walletTxStore: WalletTxStore = {}; + let cachedBalances: Record = {}; + let loadedFromEncrypted = false; + + if (encAccountData) { + const accountDataPt = await decryptGCM( + key, + new Uint8Array(encAccountData.cipher.iv), + new Uint8Array(encAccountData.cipher.ct) + ).catch(() => null); + + if (accountDataPt) { + const accountData = JSON.parse(accountDataPt) as EncryptedAccountData; + utxoStore = accountData.utxoStore || {}; + walletTxStore = accountData.walletTxStore || {}; + cachedBalances = accountData.cachedBalances || {}; + loadedFromEncrypted = true; + } + } + + // Key is only cached after unlock() runs, so migration has always happened. + // No legacy fallback needed. this.mnemonic = payload.mnemonic; this.encryptionKey = key; + this.utxoStore = utxoStore; + this.walletTxStore = walletTxStore; + this.cachedBalances = cachedBalances; this.state = { locked: false, @@ -1106,22 +1137,8 @@ export class Vault { storedNote.pendingTxId = walletTxId; newChange++; } else { - // Incoming transaction - create a WalletTransaction record - const incomingTxId = crypto.randomUUID(); - const now = Date.now(); - - await this.addWalletTransaction({ - id: incomingTxId, - txHash: newUTXO.sourceHash, - accountAddress, - direction: 'incoming', - createdAt: now, - updatedAt: now, - status: 'confirmed', - amount: newUTXO.assets, - receivedNoteIds: [newUTXO.noteId], - }); - + // Don't create WalletTransaction records for incoming UTXOs. + // Only outgoing transactions appear in history. Balance still updates correctly. newIncoming++; }