Clean up remaining console statements, log recovery success

This commit is contained in:
minibits-cash
2026-09-29 09:31:45 +02:00
parent fd68398f3c
commit 718029a6e5
7 changed files with 53 additions and 9 deletions
+2 -3
View File
@@ -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'));
}
/**
+2 -1
View File
@@ -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.
+7 -1
View File
@@ -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()
+17 -1
View File
@@ -254,4 +254,20 @@ const log = logger.createLogger({
asyncFunc: (transport: any) => setTimeout(transport, 0),
})
export { log }
/**
* 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<string, any> = {}): void => {
if (__DEV__) {
log.info(message, params)
return
}
if (!userSettings().isLoggerOn) return
Sentry.logger.info(redactSensitive(fixTagSpacing(message)), redactParams(params))
}
export { log, logMilestone }
+1 -1
View File
@@ -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
}
}
@@ -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<WalletTaskResult> =
},
})
logMilestone('[handleInFlightByMintTask] Recovery succeeded: in-flight request replayed', {
type: TransactionType.RECEIVE,
})
break
}
@@ -157,6 +160,9 @@ const handleInFlightByMintTask = async (mint: Mint): Promise<WalletTaskResult> =
},
})
logMilestone('[handleInFlightByMintTask] Recovery succeeded: in-flight request replayed', {
type: TransactionType.TOPUP,
})
break
}
@@ -233,6 +239,9 @@ const handleInFlightByMintTask = async (mint: Mint): Promise<WalletTaskResult> =
Number(quoteResponse.amount_issued ?? 0),
)
logMilestone('[handleInFlightByMintTask] Recovery succeeded: in-flight request replayed', {
type: TransactionType.TOPUP_ONCHAIN,
})
break
}
@@ -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<WalletTaskRe
operationType: row.operationType,
outcome,
})
// Production monitoring signal. Operation type and outcome only — no ids or
// amounts. A lost swap needs the user to act, so that one is a real error.
if (outcome === 'swap-lost') {
log.error('[resolveInterruptedOperationsTask] Recovery incomplete, seed recovery needed', {
operationType: row.operationType,
outcome,
})
} else if (outcome !== 'unresolved') {
logMilestone('[resolveInterruptedOperationsTask] Recovery succeeded', {
operationType: row.operationType,
outcome,
})
}
} catch (e: any) {
// Held until the next sweep — most often the mint is unreachable.
errors.push(`tId=${row.transactionId}: ${e.message}`)