mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-05 19:28:26 +00:00
Clean up remaining console statements, log recovery success
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
diff --git a/node_modules/@scure/bip39/index.js b/node_modules/@scure/bip39/index.js
|
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
|
--- a/node_modules/@scure/bip39/index.js
|
||||||
+++ b/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';
|
@@ -4,6 +4,7 @@ import { sha256, sha512 } from '@noble/hashes/sha2.js';
|
||||||
@@ -10,13 +10,12 @@ index a7db5ca..a7f0e85 100644
|
|||||||
// Japanese wordlist
|
// Japanese wordlist
|
||||||
const isJapanese = (wordlist) => wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093';
|
const isJapanese = (wordlist) => wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093';
|
||||||
// Normalization replaces equivalent sequences of characters
|
// 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])
|
* // new Uint8Array([...64 bytes])
|
||||||
*/
|
*/
|
||||||
export function mnemonicToSeedSync(mnemonic, passphrase = '') {
|
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 });
|
||||||
+ //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'));
|
+ return new Uint8Array(quickCrypto.pbkdf2Sync(normalize(mnemonic).nfkd, psalt(passphrase), 2048, 64, 'sha512'));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-1
@@ -8,6 +8,7 @@ import en from "../i18n_messages/en.json"
|
|||||||
import sk from "../i18n_messages/sk.json"
|
import sk from "../i18n_messages/sk.json"
|
||||||
import es from "../i18n_messages/es.json"
|
import es from "../i18n_messages/es.json"
|
||||||
import pt from "../i18n_messages/pt.json"
|
import pt from "../i18n_messages/pt.json"
|
||||||
|
import { log } from "../services/logService"
|
||||||
|
|
||||||
type Translations = typeof en;
|
type Translations = typeof en;
|
||||||
export const i18n = new I18n()
|
export const i18n = new I18n()
|
||||||
@@ -57,7 +58,7 @@ const localeJSFormat = fullLocaleRN.includes("-")
|
|||||||
const deviceLocales = getLocales()
|
const deviceLocales = getLocales()
|
||||||
i18n.locale = deviceLocales[0].languageCode
|
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.
|
* Builds up valid keypaths for translations.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import type { RootStore } from '../RootStore'
|
|||||||
import { captureOrphanedSeed, Database, MMKVStorage } from '../../services'
|
import { captureOrphanedSeed, Database, MMKVStorage } from '../../services'
|
||||||
import type { MeltRecoverySeed, InFlightRequestSeed, CounterSeed } from '../../services/db'
|
import type { MeltRecoverySeed, InFlightRequestSeed, CounterSeed } from '../../services/db'
|
||||||
import type { Mint } from '../Mint'
|
import type { Mint } from '../Mint'
|
||||||
import { log } from '../../services/logService'
|
import { log, logMilestone } from '../../services/logService'
|
||||||
import { rootStoreModelVersion } from '../RootStore'
|
import { rootStoreModelVersion } from '../RootStore'
|
||||||
import AppError, { Err } from '../../utils/AppError'
|
import AppError, { Err } from '../../utils/AppError'
|
||||||
|
|
||||||
@@ -141,12 +141,18 @@ export async function setupRootStore(rootStore: RootStore, opts: SetupRootStoreO
|
|||||||
const { recoveredCount, heldCount } = proofsStore.recoverOrphanReservations()
|
const { recoveredCount, heldCount } = proofsStore.recoverOrphanReservations()
|
||||||
if (recoveredCount > 0 || heldCount > 0) {
|
if (recoveredCount > 0 || heldCount > 0) {
|
||||||
log.warn('[setupRootStore] Orphan proof reservations', {rolledBack: recoveredCount, heldForMintCheck: heldCount})
|
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.
|
// Before transactions load, so they come up with their final status.
|
||||||
const { revertedCount } = proofsStore.revertAbandonedDrafts()
|
const { revertedCount } = proofsStore.revertAbandonedDrafts()
|
||||||
if (revertedCount > 0) {
|
if (revertedCount > 0) {
|
||||||
log.warn('[setupRootStore] Reverted abandoned draft transactions', {revertedCount})
|
log.warn('[setupRootStore] Reverted abandoned draft transactions', {revertedCount})
|
||||||
|
logMilestone('[setupRootStore] Recovery succeeded: abandoned drafts reverted', {revertedCount})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const orphansRecovered = performance.now()
|
const orphansRecovered = performance.now()
|
||||||
|
|||||||
@@ -254,4 +254,20 @@ const log = logger.createLogger({
|
|||||||
asyncFunc: (transport: any) => setTimeout(transport, 0),
|
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 }
|
||||||
@@ -190,7 +190,7 @@ const isStringSafeForNFC = function (str: string): boolean {
|
|||||||
|
|
||||||
return bytes.length <= SAFE_NFC_BYTE_LIMIT
|
return bytes.length <= SAFE_NFC_BYTE_LIMIT
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Error measuring string byte size:', error)
|
log.warn('Error measuring string byte size:', error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {getEncodedToken, normalizeProofAmounts} from '@cashu/cashu-ts'
|
import {getEncodedToken, normalizeProofAmounts} from '@cashu/cashu-ts'
|
||||||
import {log} from '../../logService'
|
import {log, logMilestone} from '../../logService'
|
||||||
import {Database} from '../../sqlite'
|
import {Database} from '../../sqlite'
|
||||||
import {CashuUtils} from '../../cashu/cashuUtils'
|
import {CashuUtils} from '../../cashu/cashuUtils'
|
||||||
import {rootStoreInstance} from '../../../models'
|
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
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +160,9 @@ const handleInFlightByMintTask = async (mint: Mint): Promise<WalletTaskResult> =
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
logMilestone('[handleInFlightByMintTask] Recovery succeeded: in-flight request replayed', {
|
||||||
|
type: TransactionType.TOPUP,
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,6 +239,9 @@ const handleInFlightByMintTask = async (mint: Mint): Promise<WalletTaskResult> =
|
|||||||
Number(quoteResponse.amount_issued ?? 0),
|
Number(quoteResponse.amount_issued ?? 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logMilestone('[handleInFlightByMintTask] Recovery succeeded: in-flight request replayed', {
|
||||||
|
type: TransactionType.TOPUP_ONCHAIN,
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import {MintStatus} from '../../../models/Mint'
|
|||||||
import {Proof} from '../../../models/Proof'
|
import {Proof} from '../../../models/Proof'
|
||||||
import {Transaction, TransactionData, TransactionStatus} from '../../../models/Transaction'
|
import {Transaction, TransactionData, TransactionStatus} from '../../../models/Transaction'
|
||||||
import {NetworkError} from '../../../utils/AppError'
|
import {NetworkError} from '../../../utils/AppError'
|
||||||
import {log} from '../../logService'
|
import {log, logMilestone} from '../../logService'
|
||||||
import {Database, ReservationRow, ReservationTransactionUpdate} from '../../sqlite'
|
import {Database, ReservationRow, ReservationTransactionUpdate} from '../../sqlite'
|
||||||
import {SyncQueue} from '../../syncQueueService'
|
import {SyncQueue} from '../../syncQueueService'
|
||||||
import {CashuUtils} from '../../cashu/cashuUtils'
|
import {CashuUtils} from '../../cashu/cashuUtils'
|
||||||
@@ -58,6 +58,19 @@ const resolveInterruptedOperationsTask = async function (): Promise<WalletTaskRe
|
|||||||
operationType: row.operationType,
|
operationType: row.operationType,
|
||||||
outcome,
|
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) {
|
} catch (e: any) {
|
||||||
// Held until the next sweep — most often the mint is unreachable.
|
// Held until the next sweep — most often the mint is unreachable.
|
||||||
errors.push(`tId=${row.transactionId}: ${e.message}`)
|
errors.push(`tId=${row.transactionId}: ${e.message}`)
|
||||||
|
|||||||
Reference in New Issue
Block a user