From 718029a6e500c6d06f50e38a4b2b482338dd5b76 Mon Sep 17 00:00:00 2001 From: minibits-cash Date: Tue, 29 Sep 2026 09:31:45 +0200 Subject: [PATCH] Clean up remaining console statements, log recovery success --- patches/@scure+bip39+2.0.1.patch | 5 ++--- src/i18n/i18n.ts | 3 ++- src/models/helpers/setupRootStore.ts | 8 +++++++- src/services/logService.ts | 18 +++++++++++++++++- src/services/nfcService.ts | 2 +- .../wallet/operations/inFlightOperations.ts | 11 ++++++++++- .../wallet/operations/interruptedOperations.ts | 15 ++++++++++++++- 7 files changed, 53 insertions(+), 9 deletions(-) diff --git a/patches/@scure+bip39+2.0.1.patch b/patches/@scure+bip39+2.0.1.patch index 0a6d8ccf..d599b854 100644 --- a/patches/@scure+bip39+2.0.1.patch +++ b/patches/@scure+bip39+2.0.1.patch @@ -1,5 +1,5 @@ diff --git a/node_modules/@scure/bip39/index.js b/node_modules/@scure/bip39/index.js -index a7db5ca..a7f0e85 100644 +index a7db5ca..1dd276f 100644 --- a/node_modules/@scure/bip39/index.js +++ b/node_modules/@scure/bip39/index.js @@ -4,6 +4,7 @@ import { sha256, sha512 } from '@noble/hashes/sha2.js'; @@ -10,13 +10,12 @@ index a7db5ca..a7f0e85 100644 // Japanese wordlist const isJapanese = (wordlist) => wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093'; // Normalization replaces equivalent sequences of characters -@@ -131,7 +132,9 @@ export function mnemonicToSeed(mnemonic, passphrase = '') { +@@ -131,7 +132,8 @@ export function mnemonicToSeed(mnemonic, passphrase = '') { * // new Uint8Array([...64 bytes]) */ export function mnemonicToSeedSync(mnemonic, passphrase = '') { - return pbkdf2(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 }); + //return pbkdf2(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 }); -+ console.log('[bip39.mnemonicToSeedSync] Using ESM quickCrypto PBKDF2 Sync'); + return new Uint8Array(quickCrypto.pbkdf2Sync(normalize(mnemonic).nfkd, psalt(passphrase), 2048, 64, 'sha512')); } /** diff --git a/src/i18n/i18n.ts b/src/i18n/i18n.ts index 04b0115e..366d428f 100644 --- a/src/i18n/i18n.ts +++ b/src/i18n/i18n.ts @@ -8,6 +8,7 @@ import en from "../i18n_messages/en.json" import sk from "../i18n_messages/sk.json" import es from "../i18n_messages/es.json" import pt from "../i18n_messages/pt.json" +import { log } from "../services/logService" type Translations = typeof en; export const i18n = new I18n() @@ -57,7 +58,7 @@ const localeJSFormat = fullLocaleRN.includes("-") const deviceLocales = getLocales() i18n.locale = deviceLocales[0].languageCode -console.log('[i18n]', {deviceLocales, locale: i18n.locale}) +log.debug('[i18n]', {deviceLocales, locale: i18n.locale}) /** * Builds up valid keypaths for translations. diff --git a/src/models/helpers/setupRootStore.ts b/src/models/helpers/setupRootStore.ts index 97122f5a..72497e60 100644 --- a/src/models/helpers/setupRootStore.ts +++ b/src/models/helpers/setupRootStore.ts @@ -20,7 +20,7 @@ import type { RootStore } from '../RootStore' import { captureOrphanedSeed, Database, MMKVStorage } from '../../services' import type { MeltRecoverySeed, InFlightRequestSeed, CounterSeed } from '../../services/db' import type { Mint } from '../Mint' -import { log } from '../../services/logService' +import { log, logMilestone } from '../../services/logService' import { rootStoreModelVersion } from '../RootStore' import AppError, { Err } from '../../utils/AppError' @@ -141,12 +141,18 @@ export async function setupRootStore(rootStore: RootStore, opts: SetupRootStoreO const { recoveredCount, heldCount } = proofsStore.recoverOrphanReservations() if (recoveredCount > 0 || heldCount > 0) { log.warn('[setupRootStore] Orphan proof reservations', {rolledBack: recoveredCount, heldForMintCheck: heldCount}) + // Production monitoring signal that startup recovery runs. + logMilestone('[setupRootStore] Recovery: orphan reservations found at startup', { + rolledBack: recoveredCount, + heldForMintCheck: heldCount, + }) } // Before transactions load, so they come up with their final status. const { revertedCount } = proofsStore.revertAbandonedDrafts() if (revertedCount > 0) { log.warn('[setupRootStore] Reverted abandoned draft transactions', {revertedCount}) + logMilestone('[setupRootStore] Recovery succeeded: abandoned drafts reverted', {revertedCount}) } } const orphansRecovered = performance.now() diff --git a/src/services/logService.ts b/src/services/logService.ts index 299eab99..f4969a67 100644 --- a/src/services/logService.ts +++ b/src/services/logService.ts @@ -254,4 +254,20 @@ const log = logger.createLogger({ asyncFunc: (transport: any) => setTimeout(transport, 0), }) -export { log } \ No newline at end of file +/** + * Always-on operational signal for rare events worth monitoring in production — + * e.g. a recovery path running and succeeding. Sent to Sentry Logs at info level + * REGARDLESS of the user-selected logLevel (which defaults to ERROR, so plain + * log.info never leaves the device), without creating an error event/issue. + * Still honors isLoggerOn and the same redaction as every other log. + */ +const logMilestone = (message: string, params: Record = {}): void => { + if (__DEV__) { + log.info(message, params) + return + } + if (!userSettings().isLoggerOn) return + Sentry.logger.info(redactSensitive(fixTagSpacing(message)), redactParams(params)) +} + +export { log, logMilestone } \ No newline at end of file diff --git a/src/services/nfcService.ts b/src/services/nfcService.ts index 511e7e97..18afa096 100644 --- a/src/services/nfcService.ts +++ b/src/services/nfcService.ts @@ -190,7 +190,7 @@ const isStringSafeForNFC = function (str: string): boolean { return bytes.length <= SAFE_NFC_BYTE_LIMIT } catch (error) { - console.warn('Error measuring string byte size:', error) + log.warn('Error measuring string byte size:', error) return false } } diff --git a/src/services/wallet/operations/inFlightOperations.ts b/src/services/wallet/operations/inFlightOperations.ts index e5f295d1..983ff215 100644 --- a/src/services/wallet/operations/inFlightOperations.ts +++ b/src/services/wallet/operations/inFlightOperations.ts @@ -1,5 +1,5 @@ import {getEncodedToken, normalizeProofAmounts} from '@cashu/cashu-ts' -import {log} from '../../logService' +import {log, logMilestone} from '../../logService' import {Database} from '../../sqlite' import {CashuUtils} from '../../cashu/cashuUtils' import {rootStoreInstance} from '../../../models' @@ -117,6 +117,9 @@ const handleInFlightByMintTask = async (mint: Mint): Promise = }, }) + logMilestone('[handleInFlightByMintTask] Recovery succeeded: in-flight request replayed', { + type: TransactionType.RECEIVE, + }) break } @@ -157,6 +160,9 @@ const handleInFlightByMintTask = async (mint: Mint): Promise = }, }) + logMilestone('[handleInFlightByMintTask] Recovery succeeded: in-flight request replayed', { + type: TransactionType.TOPUP, + }) break } @@ -233,6 +239,9 @@ const handleInFlightByMintTask = async (mint: Mint): Promise = Number(quoteResponse.amount_issued ?? 0), ) + logMilestone('[handleInFlightByMintTask] Recovery succeeded: in-flight request replayed', { + type: TransactionType.TOPUP_ONCHAIN, + }) break } diff --git a/src/services/wallet/operations/interruptedOperations.ts b/src/services/wallet/operations/interruptedOperations.ts index 01343e77..a7d2915b 100644 --- a/src/services/wallet/operations/interruptedOperations.ts +++ b/src/services/wallet/operations/interruptedOperations.ts @@ -22,7 +22,7 @@ import {MintStatus} from '../../../models/Mint' import {Proof} from '../../../models/Proof' import {Transaction, TransactionData, TransactionStatus} from '../../../models/Transaction' import {NetworkError} from '../../../utils/AppError' -import {log} from '../../logService' +import {log, logMilestone} from '../../logService' import {Database, ReservationRow, ReservationTransactionUpdate} from '../../sqlite' import {SyncQueue} from '../../syncQueueService' import {CashuUtils} from '../../cashu/cashuUtils' @@ -58,6 +58,19 @@ const resolveInterruptedOperationsTask = async function (): Promise