From 51eb334950962ddeecac26b854ac0d2412053b65 Mon Sep 17 00:00:00 2001 From: minibits-cash Date: Fri, 3 Nov 2023 00:02:51 +0100 Subject: [PATCH] Privacy: turn on-off error logging, set log levels --- .github/workflows/jsCodePush-PROD.yaml | 4 +- .github/workflows/jsCodePush-TEST.yaml | 4 +- .gitignore | 1 + README.md | 1 - package.json | 1 + src/App.tsx | 13 ++- src/components/Button.tsx | 1 - src/i18n/en.ts | 7 +- src/models/Contact.ts | 7 +- src/models/ContactsStore.ts | 141 ++++++++++------------- src/models/Invoice.ts | 9 +- src/models/InvoicesStore.ts | 6 +- src/models/MintsStore.ts | 12 +- src/models/PaymentRequest.ts | 6 +- src/models/PaymentRequestsStore.ts | 6 +- src/models/ProofsStore.ts | 12 +- src/models/RelaysStore.ts | 12 +- src/models/RootStore.ts | 2 +- src/models/Transaction.ts | 5 +- src/models/TransactionsStore.ts | 49 ++++---- src/models/UserSettingsStore.ts | 44 ++++--- src/models/WalletProfileStore.ts | 12 +- src/models/helpers/setupRootStore.ts | 67 ++--------- src/navigation/TabsNavigator.tsx | 6 +- src/screens/Contacts/OwnName.tsx | 2 +- src/screens/Contacts/PrivateContacts.tsx | 2 +- src/screens/Contacts/PublicContacts.tsx | 2 +- src/screens/ContactsScreen.tsx | 2 +- src/screens/DeveloperScreen.tsx | 135 ++++++++++++++++++---- src/screens/LocalRecoveryScreen.tsx | 2 +- src/screens/MintsScreen.tsx | 2 +- src/screens/OwnKeysScreen.tsx | 2 +- src/screens/PrivacyScreen.tsx | 54 +++++++-- src/screens/ProfileScreen.tsx | 2 +- src/screens/ReceiveOptionsScreen.tsx | 2 +- src/screens/ReceiveScreen.tsx | 2 +- src/screens/ScanScreen.tsx | 2 +- src/screens/SecurityScreen.tsx | 2 +- src/screens/SendOptionsScreen.tsx | 2 +- src/screens/SendScreen.tsx | 2 +- src/screens/SettingsScreen.tsx | 17 ++- src/screens/TopupScreen.tsx | 2 +- src/screens/TranDetailScreen.tsx | 2 +- src/screens/TransferScreen.tsx | 2 +- src/screens/UpdateScreen.tsx | 3 +- src/screens/WalletScreen.tsx | 6 +- src/screens/index.ts | 2 +- src/services/cashu/cashuUtils.ts | 2 +- src/services/cashuMintClient.ts | 2 +- src/services/incomingParser.ts | 2 +- src/services/index.ts | 1 + src/services/keyChain.ts | 2 +- src/services/lightning/lightningUtils.ts | 2 +- src/services/lnurl/lnurlUtils.ts | 2 +- src/services/lnurlService.ts | 2 +- src/services/log/logTypes.ts | 7 ++ src/services/logService.ts | 78 +++++++++++++ src/services/minibitsService.ts | 2 +- src/services/mmkvStorage.ts | 6 +- src/services/nostrService.ts | 2 +- src/services/notificationService.ts | 2 +- src/services/sqlite.ts | 80 +++++++------ src/services/walletService.ts | 100 +++++++--------- src/utils/AppError.ts | 9 +- src/utils/envtypes/env.d.tsx | 8 +- src/utils/envtypes/index.ts | 5 + src/utils/logger.ts | 135 ---------------------- src/utils/poller.ts | 2 +- src/utils/useIsInternetReachable.ts | 2 +- yarn.lock | 5 + 70 files changed, 561 insertions(+), 576 deletions(-) create mode 100644 src/services/log/logTypes.ts create mode 100644 src/services/logService.ts create mode 100644 src/utils/envtypes/index.ts delete mode 100644 src/utils/logger.ts diff --git a/.github/workflows/jsCodePush-PROD.yaml b/.github/workflows/jsCodePush-PROD.yaml index c1f97cef..a3701238 100644 --- a/.github/workflows/jsCodePush-PROD.yaml +++ b/.github/workflows/jsCodePush-PROD.yaml @@ -81,9 +81,7 @@ jobs: - name: Generate .env if: ${{ env.IS_VERSION_CHANGED == 'true' }} run: |- - echo APP_ENV='PROD' >> .env - echo LOG_LEVEL='INFO' >> .env - echo SENTRY_ACTIVE='TRUE' >> .env + echo APP_ENV='PROD' >> .env echo SENTRY_DSN='${{ secrets.SENTRY_DSN }}' >> .env echo CODEPUSH_PRODUCTION_DEPLOYMENT_KEY='${{ secrets.CODEPUSH_PRODUCTION_DEPLOYMENT_KEY }}' >> .env echo NATIVE_VERSION_ANDROID='${{ env.NATIVE_VERSION }}' >> .env diff --git a/.github/workflows/jsCodePush-TEST.yaml b/.github/workflows/jsCodePush-TEST.yaml index 0f4aaf71..d0a1e950 100644 --- a/.github/workflows/jsCodePush-TEST.yaml +++ b/.github/workflows/jsCodePush-TEST.yaml @@ -81,9 +81,7 @@ jobs: - name: Generate .env if: ${{ env.IS_VERSION_CHANGED == 'true' }} run: |- - echo APP_ENV='TEST' >> .env - echo LOG_LEVEL='INFO' >> .env - echo SENTRY_ACTIVE='TRUE' >> .env + echo APP_ENV='TEST' >> .env echo SENTRY_DSN='${{ secrets.SENTRY_DSN }}' >> .env echo CODEPUSH_STAGING_DEPLOYMENT_KEY='${{ secrets.CODEPUSH_STAGING_DEPLOYMENT_KEY }}' >> .env echo NATIVE_VERSION_ANDROID='${{ env.NATIVE_VERSION }}' >> .env diff --git a/.gitignore b/.gitignore index f4afa3c0..f527cef7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # App specific .env +.vscode/ # OSX # .DS_Store diff --git a/README.md b/README.md index 59189539..1c6b794c 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,6 @@ After the dependecies are installed, continue to create the following .env file ```bash APP_ENV = 'DEV' -LOG_LEVEL = 'TRACE' SENTRY_ACTIVE = 'FALSE' ``` diff --git a/package.json b/package.json index f05aa8cf..f375ada3 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "react-native-gesture-handler": "^2.9.0", "react-native-json-tree": "^1.3.0", "react-native-keychain": "^8.1.1", + "react-native-logs": "^5.0.1", "react-native-mmkv": "^2.8.0", "react-native-modal": "^13.0.1", "react-native-pager-view": "^6.2.0", diff --git a/src/App.tsx b/src/App.tsx index 8a29c3ec..aa8ea37e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,8 +6,7 @@ import { JS_BUNDLE_VERSION, NATIVE_VERSION_ANDROID, CODEPUSH_STAGING_DEPLOYMENT_KEY, - CODEPUSH_PRODUCTION_DEPLOYMENT_KEY, - SENTRY_ACTIVE, + CODEPUSH_PRODUCTION_DEPLOYMENT_KEY, } from '@env' import codePush from 'react-native-code-push' import FlashMessage from "react-native-flash-message" @@ -24,13 +23,14 @@ import {useInitialRootStore, useStores} from './models' import {Database} from './services' import {ErrorBoundary} from './screens/ErrorScreen/ErrorBoundary' import Config from './config' -import {Env, log, SentryActive} from './utils/logger' +import {log} from './services' +import {Env} from './utils/envtypes' import AppError from './utils/AppError' setSizeMattersBaseWidth(375) setSizeMattersBaseHeight(812) -if (!__DEV__ && SENTRY_ACTIVE === SentryActive.TRUE) { +if (!__DEV__) { Sentry.init({ dsn: SENTRY_DSN, environment: APP_ENV, @@ -55,7 +55,7 @@ function App(props: AppProps) { const {userSettingsStore} = useStores() const {rehydrated} = useInitialRootStore(() => { // This runs after the root store has been initialized and rehydrated from storage. - log.trace('Root store rehydrated', [], 'useInitialRootStore') + // Creates and opens a sqlite database that stores transactions history and user settings. // It triggers db migrations if database version has changed. @@ -63,7 +63,8 @@ function App(props: AppProps) { Database.getDatabaseVersion() // Syncs userSettings store with the database where they are persisted - userSettingsStore.loadUserSettings() + userSettingsStore.loadUserSettings() + log.trace('[useInitialRootStore]', 'Root store rehydrated') }) if (!rehydrated) { diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 41be95e7..a1555e94 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -10,7 +10,6 @@ import { import {moderateScale, scale, verticalScale} from '@gocodingnow/rn-size-matters' import { colors, spacing, typography, useThemeColor } from "../theme" import { Text, TextProps } from "./Text" -import { log } from "../utils/logger" type Presets = keyof typeof $viewPresets diff --git a/src/i18n/en.ts b/src/i18n/en.ts index baba06a8..a8f135ef 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -171,7 +171,9 @@ const en = { privacyScreen: { torDaemon: "Use Tor network", torDaemonDescription: "Allow connections with mints through Tor .onion addresses.", - torStatus: "Tor status" + torStatus: "Tor status", + logger: "Enable logging", + loggerDescription: "Log anonymous error information in order to identify and fix wallet bugs during beta testing. Switch off for best privacy.", }, updateScreen: { updateAvailable: "Update is available", @@ -192,7 +194,8 @@ const en = { resetDescription: "This will wipe out all local data from storage and from the local database. Do only during development or testing.", go: "Let's go!", devOptions: "Developer options", - info: "About Minibits wallet" + info: "About Minibits wallet", + logLevel: "Log level" }, errorScreen: { title: "Something went wrong!", diff --git a/src/models/Contact.ts b/src/models/Contact.ts index f30d3254..52fac8c5 100644 --- a/src/models/Contact.ts +++ b/src/models/Contact.ts @@ -1,6 +1,6 @@ import {Instance, SnapshotIn, SnapshotOut, types} from 'mobx-state-tree' import { MINIBITS_NIP05_DOMAIN, MINIBITS_SERVER_API_HOST } from '@env' -import { log } from '../utils/logger' +import { log } from '../services/logService' export type ContactData = { [index: string]: any @@ -28,10 +28,9 @@ export const ContactModel = types }) .actions(self => ({ refreshPicture() { - const cleaned = MINIBITS_SERVER_API_HOST + '/profile/avatar/' + self.pubkey // remove refresh suffix - log.trace('Cleaned', cleaned) + const cleaned = MINIBITS_SERVER_API_HOST + '/profile/avatar/' + self.pubkey // remove refresh suffix self.picture = cleaned + '?r=' + Math.floor(Math.random() * 100) // force url refresh - log.trace('Refreshed', self.picture) + }, })) .views(self => ({ diff --git a/src/models/ContactsStore.ts b/src/models/ContactsStore.ts index 197ec168..667430ad 100644 --- a/src/models/ContactsStore.ts +++ b/src/models/ContactsStore.ts @@ -12,15 +12,14 @@ import { ContactModel, Contact, } from './Contact' - import {log} from '../utils/logger' + import {log} from '../services/logService' // export const maxContactsInModel = 10 export const ContactsStoreModel = types .model('ContactsStore', { contacts: types.array(ContactModel), - publicPubkey: types.maybe(types.string), - publicRelay: types.maybe(types.string), // TODO remove, replaced by relaysStore + publicPubkey: types.maybe(types.string), lastPendingReceivedCheck: types.maybe(types.number), // UNIX timestamp receivedEventIds: types.optional(types.array(types.string), []) }) @@ -33,91 +32,71 @@ import { findByNpub: (npub: string) => { const c = self.contacts.find(c => c.npub === npub) return c ? c : undefined - }, - removeContact: (removedContact: Contact) => { - let contactInstance: Contact | undefined - - if (isStateTreeNode(removedContact)) { - contactInstance = removedContact - } else { - contactInstance = self.contacts.find( - (c: Contact) => c.pubkey === (removedContact as Contact).pubkey, - ) - } - - if (contactInstance) { - detach(contactInstance) // needed - destroy(contactInstance) - log.trace('Contact removed from ContactsStore') - } - }, + }, })) .actions(self => ({ - addContact(newContact: Contact) { + addContact(newContact: Contact) { - newContact.createdAt = Math.floor(Date.now() / 1000) - - const contactInstance = ContactModel.create(newContact) - self.contacts.push(contactInstance) - - log.trace('New contact added to the ContactsStore', newContact, 'addContact') - - return contactInstance - }, - refreshPicture(pubkey: string) { + newContact.createdAt = Math.floor(Date.now() / 1000) + + const contactInstance = ContactModel.create(newContact) + self.contacts.push(contactInstance) + + log.debug('[addContact]', 'New contact added to the ContactsStore', newContact) + + return contactInstance + }, + refreshPicture(pubkey: string) { - const contactInstance = self.findByPubkey(pubkey) - if (contactInstance) { - contactInstance.refreshPicture() - log.trace('Contact picture refreshed in ContactsStore') - } + const contactInstance = self.findByPubkey(pubkey) + if (contactInstance) { + contactInstance.refreshPicture() + log.debug('[refreshPicture]', 'Contact picture refreshed in ContactsStore') + } - return contactInstance - }, - saveNote (pubkey: string, note: string) { - const contactInstance = self.findByPubkey(pubkey) - if (contactInstance) { - contactInstance.noteToSelf = note - log.trace('Contact note updated in ContactsStore') - } - }, - removeContact(contactToBeRemoved: Contact) { - let contactInstance: Contact | undefined + return contactInstance + }, + saveNote (pubkey: string, note: string) { + const contactInstance = self.findByPubkey(pubkey) + if (contactInstance) { + contactInstance.noteToSelf = note + log.debug('[saveNote]', 'Contact note updated in ContactsStore') + } + }, + removeContact(contactToBeRemoved: Contact) { + let contactInstance: Contact | undefined - if (isStateTreeNode(contactToBeRemoved)) { - contactInstance = contactToBeRemoved - } else { - contactInstance = self.findByNpub((contactToBeRemoved as Contact).npub) - } + if (isStateTreeNode(contactToBeRemoved)) { + contactInstance = contactToBeRemoved + } else { + contactInstance = self.findByNpub((contactToBeRemoved as Contact).npub) + } - if (contactInstance) { - destroy(contactInstance) - log.info('Contact removed from MintsStore') - } - }, - removeAllContacts() { - self.contacts.clear() - log.info('Removed all Contacts from ContactsStore') - }, - setPublicPubkey(publicPubkey: string) { - self.publicPubkey = publicPubkey - log.info('setPublicPubkey', publicPubkey) - }, - setPublicRelay(publicRelay: string) { - self.publicRelay = publicRelay - log.info('setPublicRelay', publicRelay) - }, - setLastPendingReceivedCheck() { - const ts: number = Math.floor(Date.now() / 1000) - log.trace('Timestamp', {ts}, 'setLastPendingReceivedCheck') - self.lastPendingReceivedCheck = ts - }, - addReceivedEventId(id: string) { - self.receivedEventIds.push(id) - }, - eventAlreadyReceived(id: string) { - return self.receivedEventIds.includes(id) - }, + if (contactInstance) { + detach(contactInstance) // needed + destroy(contactInstance) + log.debug('[removeContact]', 'Contact removed from MintsStore') + } + }, + removeAllContacts() { + self.contacts.clear() + log.debug('[removeAllContacts]', 'Removed all Contacts from ContactsStore') + }, + setPublicPubkey(publicPubkey: string) { + self.publicPubkey = publicPubkey + log.debug('[setPublicPubkey]', publicPubkey) + }, + setLastPendingReceivedCheck() { + const ts: number = Math.floor(Date.now() / 1000) + log.trace('[setLastPendingReceivedCheck]', {ts}) + self.lastPendingReceivedCheck = ts + }, + addReceivedEventId(id: string) { + self.receivedEventIds.push(id) + }, + eventAlreadyReceived(id: string) { + return self.receivedEventIds.includes(id) + }, })) .views(self => ({ get count() { diff --git a/src/models/Invoice.ts b/src/models/Invoice.ts index a71c9851..2c492279 100644 --- a/src/models/Invoice.ts +++ b/src/models/Invoice.ts @@ -1,7 +1,7 @@ import {Instance, SnapshotIn, SnapshotOut, types} from 'mobx-state-tree' import {LightningUtils} from '../services/lightning/lightningUtils' import {withSetPropAction} from './helpers/withSetPropAction' -import {log} from '../utils/logger' +import {log} from '../services/logService' import addSeconds from 'date-fns/addSeconds' /** @@ -16,7 +16,7 @@ export const InvoiceModel = types description: types.optional(types.string, ''), paymentHash: types.string, expiry: types.optional(types.number, 600), - memo: types.optional(types.string, 'Topup of minibits wallet'), + memo: types.optional(types.string, 'Topup of Minibits wallet'), transactionId: types.number, expiresAt: types.maybe(types.Date), createdAt: types.optional(types.Date, new Date()), @@ -29,10 +29,7 @@ export const InvoiceModel = types const expiresAt = addSeconds(new Date(timestamp as number * 1000), expiry as number) - log.trace( - `Invoice expiry is ${expiry}, setting expiresAt to ${expiresAt}`, - ) - + log.trace('[setExpiresAt]', `Invoice expiry is ${expiry}, setting expiresAt to ${expiresAt}`) self.expiresAt = new Date(expiresAt) }, })) diff --git a/src/models/InvoicesStore.ts b/src/models/InvoicesStore.ts index 88fd034d..56ae9a11 100644 --- a/src/models/InvoicesStore.ts +++ b/src/models/InvoicesStore.ts @@ -7,7 +7,7 @@ import { } from 'mobx-state-tree' import {withSetPropAction} from './helpers/withSetPropAction' import {InvoiceModel, Invoice} from './Invoice' -import {log} from '../utils/logger' +import {log} from '../services/logService' export const InvoicesStoreModel = types .model('Invoices', { @@ -31,7 +31,7 @@ export const InvoicesStoreModel = types invoiceInstance.setExpiresAt() self.invoices.push(invoiceInstance) - log.info('New invoice added to InvoicesStore', newInvoice) + log.info('[addInvoice]', 'New invoice added to InvoicesStore', newInvoice) return invoiceInstance }, @@ -49,7 +49,7 @@ export const InvoicesStoreModel = types } if (invoiceInstance) { - log.trace('Invoice to be removed from InvoicesStore', invoiceToRemove) + log.info('[removeInvoice]', 'Invoice to be removed from InvoicesStore', invoiceToRemove) destroy(invoiceInstance) } }, diff --git a/src/models/MintsStore.ts b/src/models/MintsStore.ts index 0ff106b6..57bb9658 100644 --- a/src/models/MintsStore.ts +++ b/src/models/MintsStore.ts @@ -7,7 +7,7 @@ import { } from 'mobx-state-tree' import {withSetPropAction} from './helpers/withSetPropAction' import {MintModel, Mint} from './Mint' -import {log} from '../utils/logger' +import {log} from '../services/logService' export type MintsByHostname = { hostname: string @@ -44,12 +44,12 @@ export const MintsStoreModel = types self.mints.push(mintInstance) - log.info('New mint added to the MintsStore', newMint.mintUrl) + log.info('[addMint]', 'New mint added to the MintsStore', newMint.mintUrl) }, removeMint(mintToBeRemoved: Mint) { if (self.blockedMintUrls.some(m => m === mintToBeRemoved.mintUrl)) { self.blockedMintUrls.remove(mintToBeRemoved.mintUrl) - log.info('Mint removed from blockedMintUrls') + log.debug('[removeMint]', 'Mint removed from blockedMintUrls') } let mintInstance: Mint | undefined @@ -62,16 +62,16 @@ export const MintsStoreModel = types if (mintInstance) { destroy(mintInstance) - log.trace('Mint removed from MintsStore') + log.info('[removeMint]', 'Mint removed from MintsStore') } }, blockMint(mintToBeBlocked: Mint) { self.blockedMintUrls.push(mintToBeBlocked.mintUrl) - log.trace('Mint blocked in MintsStore') + log.debug('[blockMint]', 'Mint blocked in MintsStore') }, unblockMint(blockedMint: Mint) { self.blockedMintUrls.remove(blockedMint.mintUrl) - log.trace('Mint unblocked in MintsStore') + log.debug('[unblockMint]', 'Mint unblocked in MintsStore') }, })) .views(self => ({ diff --git a/src/models/PaymentRequest.ts b/src/models/PaymentRequest.ts index 5fdbe497..1938ced3 100644 --- a/src/models/PaymentRequest.ts +++ b/src/models/PaymentRequest.ts @@ -1,7 +1,7 @@ import {Instance, SnapshotIn, SnapshotOut, types} from 'mobx-state-tree' import {LightningUtils} from '../services/lightning/lightningUtils' import {withSetPropAction} from './helpers/withSetPropAction' -import {log} from '../utils/logger' +import {log} from '../services/logService' import addSeconds from 'date-fns/addSeconds' /** @@ -40,9 +40,7 @@ export const PaymentRequestModel = types const expiresAt = addSeconds(new Date(timestamp * 1000), expiry as number) - log.trace( - `PaymentRequest expiry is ${expiry}, setting expiresAt to ${expiresAt}`, - ) + log.debug('[setExpiresAt]', `PaymentRequest expiry is ${expiry}, setting expiresAt to ${expiresAt}`) self.expiresAt = new Date(expiresAt) }, setStatus(status: PaymentRequestStatus) { diff --git a/src/models/PaymentRequestsStore.ts b/src/models/PaymentRequestsStore.ts index baad8965..297088c0 100644 --- a/src/models/PaymentRequestsStore.ts +++ b/src/models/PaymentRequestsStore.ts @@ -8,7 +8,7 @@ import { } from 'mobx-state-tree' import {withSetPropAction} from './helpers/withSetPropAction' import {PaymentRequestModel, PaymentRequest, PaymentRequestStatus} from './PaymentRequest' -import {log} from '../utils/logger' +import {log} from '../services/logService' import AppError, { Err } from '../utils/AppError' import {LightningUtils} from '../services/lightning/lightningUtils' import isBefore from 'date-fns/isBefore' @@ -70,7 +70,7 @@ export const PaymentRequestsStoreModel = types paymentRequestInstance.setExpiresAt() self.paymentRequests.push(paymentRequestInstance) - log.info('New paymentRequest added to PaymentRequestsStore', newPaymentRequest) + log.info('[addPaymentRequest]', 'New paymentRequest added to PaymentRequestsStore', newPaymentRequest) return paymentRequestInstance }, @@ -90,7 +90,7 @@ export const PaymentRequestsStoreModel = types if (paymentRequestInstance) { detach(paymentRequestInstance) destroy(paymentRequestInstance) - log.info('PaymentRequest removed from the store') + log.info('[removePaymentRequest]', 'PaymentRequest removed from the store') } }, diff --git a/src/models/ProofsStore.ts b/src/models/ProofsStore.ts index f2e7f9cf..1c24bce6 100644 --- a/src/models/ProofsStore.ts +++ b/src/models/ProofsStore.ts @@ -7,7 +7,7 @@ import { } from 'mobx-state-tree' import {withSetPropAction} from './helpers/withSetPropAction' import {ProofModel, Proof} from './Proof' -import {log} from '../utils/logger' +import {log} from '../services/logService' import {getRootStore} from './helpers/getRootStore' import AppError, {Err} from '../utils/AppError' import {Mint, MintBalance} from './Mint' @@ -71,7 +71,7 @@ export const ProofsStoreModel = types } } - log.trace(`Added new ${newProofs.length}${isPending ? ' pending' : ''} proofs to ProofsStore`,) + log.debug('[addProofs]', `Added new ${newProofs.length}${isPending ? ' pending' : ''} proofs to ProofsStore`,) const rootStore = getRootStore(self) const {userSettingsStore} = rootStore @@ -113,7 +113,7 @@ export const ProofsStoreModel = types proofs.replace(proofs.filter(proof => !proofsToRemove.includes(proof))) - log.trace(`${count} ${(isPending) ? 'pending' : ''} proofs removed from ProofsStore`) + log.debug('[removeProofs]', `${count} ${(isPending) ? 'pending' : ''} proofs removed from ProofsStore`) } catch (e: any) { throw new AppError(Err.STORAGE_ERROR, e.message.toString()) @@ -171,9 +171,7 @@ export const ProofsStoreModel = types totalPendingBalance, mintBalances, mintPendingBalances, - } - - log.trace(balances) + } return balances }, @@ -199,7 +197,7 @@ export const ProofsStoreModel = types return maxBalance }, balances[0]) - log.trace('Max Balance', maxBalance, 'getMintBalanceWithMaxBalance') + log.debug('[getMintBalanceWithMaxBalance]', maxBalance) return maxBalance }, getProofsToSend: (amount: number, proofs: Proof[]) => { diff --git a/src/models/RelaysStore.ts b/src/models/RelaysStore.ts index d9532664..14620d4b 100644 --- a/src/models/RelaysStore.ts +++ b/src/models/RelaysStore.ts @@ -8,7 +8,7 @@ import { } from 'mobx-state-tree' import {withSetPropAction} from './helpers/withSetPropAction' import {RelayModel, Relay} from './Relay' -import {log} from '../utils/logger' +import {log} from '../services/logService' import { MINIBITS_RELAY_URL } from '@env' import { NostrClient } from '../services' @@ -46,19 +46,19 @@ export const RelaysStoreModel = types relayInstance?.setError(error) } - log.trace('Relay updated in the RelaysStore', {relay}, 'addOrUpdateRelay') + log.debug('[addOrUpdateRelay]', 'Relay updated in the RelaysStore', {relay}) } else { - log.trace('Passed URL', relay.url) + log.trace('[addOrUpdateRelay]', 'Passed URL', relay.url) const normalized = NostrClient.getNormalizedRelayUrl(relay.url) - log.trace('Normalized URL', normalized) + log.trace('[addOrUpdateRelay]', 'Normalized URL', normalized) relay.url = normalized const relayInstance = RelayModel.create(relay) relayInstance.setHostname() self.relays.push(relayInstance) - log.info('New relay added to the RelaysStore', {relay}, 'addOrUpdateRelay') + log.info('[addOrUpdateRelay]', 'New relay added to the RelaysStore', {relay}) } }, removeRelay(relayUrl: string) { @@ -68,7 +68,7 @@ export const RelaysStoreModel = types if (relayInstance) { detach(relayInstance) destroy(relayInstance) - log.info('Relay removed from RelaysStore', {relayUrl}, 'removeRelay') + log.info('[removeRelay]', 'Relay removed from RelaysStore', {relayUrl}) } }, })) diff --git a/src/models/RootStore.ts b/src/models/RootStore.ts index 4b4bd18c..40377649 100644 --- a/src/models/RootStore.ts +++ b/src/models/RootStore.ts @@ -9,7 +9,7 @@ import {PaymentRequestsStoreModel} from './PaymentRequestsStore' import {ProofsStoreModel} from './ProofsStore' import {RelaysStoreModel} from './RelaysStore' -export const rootStoreModelVersion = 5 // Update this if model changes require migrations defined in setupRootStore.ts +export const rootStoreModelVersion = 6 // Update this if model changes require migrations defined in setupRootStore.ts /** * A RootStore model. diff --git a/src/models/Transaction.ts b/src/models/Transaction.ts index fe26cf29..886bf76c 100644 --- a/src/models/Transaction.ts +++ b/src/models/Transaction.ts @@ -1,5 +1,5 @@ import {Instance, SnapshotIn, SnapshotOut, types} from 'mobx-state-tree' -import { log } from '../utils/logger' +import { log } from '../services/logService' export interface TransactionRecord { id?: number @@ -13,7 +13,8 @@ export interface TransactionRecord { balanceAfter?: number | null noteToSelf?: string | null tags?: Array | null - status: TransactionStatus + status: TransactionStatus + createdAt: Date } export type TransactionData = { diff --git a/src/models/TransactionsStore.ts b/src/models/TransactionsStore.ts index 2324a1b9..922f60b3 100644 --- a/src/models/TransactionsStore.ts +++ b/src/models/TransactionsStore.ts @@ -14,7 +14,7 @@ import { TransactionRecord, } from './Transaction' import {Database} from '../services' -import {log} from '../utils/logger' +import {log} from '../services/logService' export const maxTransactionsInModel = 10 @@ -27,21 +27,21 @@ export const TransactionsStoreModel = types findById: (id: number) => { const tx = self.transactions.find(tx => tx.id === id) return tx ? tx : undefined - }, + } + })) + .actions(self => ({ removeTransaction: (removedTransaction: Transaction) => { let transactionInstance: Transaction | undefined if (isStateTreeNode(removedTransaction)) { transactionInstance = removedTransaction } else { - transactionInstance = self.transactions.find( - (t: Transaction) => t.id === (removedTransaction as Transaction).id, - ) + transactionInstance = self.findById((removedTransaction as Transaction).id as number) } if (transactionInstance) { destroy(transactionInstance) - log.trace('Transaction removed from TransactionsStore') + log.info('[removeTransaction]', 'Transaction removed from TransactionsStore') } }, removeOldTransactions: () => { @@ -53,10 +53,9 @@ export const TransactionsStoreModel = types .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()) // Sort transactions by createdAt in descending order .splice(maxTransactionsInModel) // Remove transactions beyond the desired number to keep - log.trace( - `${ + log.debug('[removeOldTransactions]', `${ numTransactions - maxTransactionsInModel - } transaction(s) removed from TransactionsStore`, + } transaction(s) removed from TransactionsStore`, ) } }, @@ -73,11 +72,7 @@ export const TransactionsStoreModel = types const transactionInstance = TransactionModel.create(inStoreTransaction) self.transactions.push(transactionInstance) - log.trace( - 'New transaction added to the TransactionsStore', - [], - 'addTransaction', - ) + log.debug('[addTransaction]', 'New transaction added to the TransactionsStore') // Purge the oldest transaction from the model if the maximum number of transactions is reached if (self.transactions.length > maxTransactionsInModel) { @@ -95,13 +90,12 @@ export const TransactionsStoreModel = types const inStoreTransaction = {...dbTransaction, createdAt} const transactionInstance = TransactionModel.create(inStoreTransaction) - inStoreTransactions.push(transactionInstance) + inStoreTransactions.push(transactionInstance as Transaction) } self.transactions.push(...inStoreTransactions) - log.trace( - `${inStoreTransactions.length} new transactions added to TransactionsStore`, + log.debug('[addTransactionsToModel]', `${inStoreTransactions.length} new transactions added to TransactionsStore`, ) }, updateStatus: flow(function* updateStatus( @@ -117,10 +111,7 @@ export const TransactionsStoreModel = types if (transactionInstance) { transactionInstance.status = status transactionInstance.data = data - log.trace( - 'Transaction status and data updated in TransactionsStore', - 'updateStatus', - ) + log.debug('[updateStatus]', 'Transaction status and data updated in TransactionsStore', {id, status}) } return transactionInstance @@ -146,7 +137,7 @@ export const TransactionsStoreModel = types transactionInstance.data = JSON.stringify(updatedData) - log.trace('Transaction status and data updated in TransactionsStore',[],'updateStatuses',) + log.debug('[updateStatuses]', 'Transaction statuses and data updated in TransactionsStore', {ids, status}) } } }), @@ -162,7 +153,7 @@ export const TransactionsStoreModel = types // Update in the model if (transactionInstance) { transactionInstance.balanceAfter = balanceAfter - log.trace('Transaction balanceAfter updated in TransactionsStore',[],'updateBalanceAfter',) + log.debug('[updateBalanceAfter]', 'Transaction balanceAfter updated in TransactionsStore', {balanceAfter}) } return transactionInstance @@ -176,7 +167,7 @@ export const TransactionsStoreModel = types // Update in the model if (transactionInstance) { transactionInstance.fee = fee - log.trace('Transaction fee updated in TransactionsStore',[],'updateFee') + log.debug('[updateFee]', 'Transaction fee updated in TransactionsStore', {fee}) } return transactionInstance @@ -193,7 +184,7 @@ export const TransactionsStoreModel = types // Update in the model if (transactionInstance) { transactionInstance.amount = amount - log.trace('Transaction amount updated in TransactionsStore') + log.debug('[updateReceivedAmount]', 'Transaction amount updated in TransactionsStore', {id, amount}) } return transactionInstance @@ -208,7 +199,7 @@ export const TransactionsStoreModel = types // TODO how to handle missing UI updates for older notes that are stored in db only if (transactionInstance) { transactionInstance.noteToSelf = note - log.trace('Transaction note updated in TransactionsStore') + log.debug('[saveNote]', 'Transaction note updated in TransactionsStore', {note}) } }), updateSentFrom: flow(function* updateSentFrom(id: number, sentFrom: string) { @@ -217,7 +208,7 @@ export const TransactionsStoreModel = types const transactionInstance = self.findById(id) if (transactionInstance) { transactionInstance.sentFrom = sentFrom - log.trace('Transaction sentFrom updated in TransactionsStore') + log.debug('[updateSentFrom]', 'Transaction sentFrom updated in TransactionsStore', {id, sentFrom}) } }), updateSentTo: flow(function* updateSentTo(id: number, sentTo: string) { // @@ -226,12 +217,12 @@ export const TransactionsStoreModel = types const transactionInstance = self.findById(id) if (transactionInstance) { transactionInstance.sentTo = sentTo - log.trace('Transaction sentTo updated in TransactionsStore') + log.debug('[updateSentTo]', 'Transaction sentTo updated in TransactionsStore', {id, sentTo}) } }), removeAllTransactions() { self.transactions.clear() - log.info('Removed all transactions from TransactionsStore') + log.debug('[removeAllTransactions]', 'Removed all transactions from TransactionsStore') }, })) .views(self => ({ diff --git a/src/models/UserSettingsStore.ts b/src/models/UserSettingsStore.ts index 280af9f4..6eeb1c5b 100644 --- a/src/models/UserSettingsStore.ts +++ b/src/models/UserSettingsStore.ts @@ -1,7 +1,7 @@ import {Instance, SnapshotOut, types, flow} from 'mobx-state-tree' import {Database} from '../services' import {MMKVStorage} from '../services' -import {log} from '../utils/logger' +import {LogLevel} from '../services/log/logTypes' export type UserSettings = { id?: number @@ -10,6 +10,8 @@ export type UserSettings = { isStorageEncrypted: boolean | 0 | 1 isLocalBackupOn: boolean | 0 | 1 isTorDaemonOn: boolean | 0 | 1 + isLoggerOn: boolean | 0 | 1 + logLevel: LogLevel } export const UserSettingsStoreModel = types @@ -20,6 +22,8 @@ export const UserSettingsStoreModel = types isStorageEncrypted: types.optional(types.boolean, false), isLocalBackupOn: types.optional(types.boolean, true), isTorDaemonOn: types.optional(types.boolean, false), + isLoggerOn: types.optional(types.boolean, true), + logLevel: types.optional(types.frozen(), LogLevel.ERROR) }) .actions(self => ({ loadUserSettings: () => { @@ -28,38 +32,38 @@ export const UserSettingsStoreModel = types isOnboarded, isStorageEncrypted, isLocalBackupOn, - isTorDaemonOn + isTorDaemonOn, + isLoggerOn, + logLevel } = Database.getUserSettings() const booleanIsOnboarded = isOnboarded === 1 const booleanIsStorageEncrypted = isStorageEncrypted === 1 const booleanIsLocalBackupOn = isLocalBackupOn === 1 - const booleanIsTorDaemonOn = isTorDaemonOn === 1 + const booleanIsTorDaemonOn = isTorDaemonOn === 1 + const booleanIsLoggerOn = isLoggerOn === 1 self.walletId = walletId as string self.isOnboarded = booleanIsOnboarded as boolean self.isStorageEncrypted = booleanIsStorageEncrypted as boolean self.isLocalBackupOn = booleanIsLocalBackupOn as boolean self.isTorDaemonOn = booleanIsTorDaemonOn as boolean + self.isLoggerOn = booleanIsLoggerOn as boolean + self.logLevel = logLevel as LogLevel }, setWalletId: (walletId: string) => { Database.updateUserSettings({...self, walletId}) self.walletId = walletId - - log.info('walletId updated', {walletId}, 'setWalletId') + return walletId }, setIsOnboarded: (isOnboarded: boolean) => { Database.updateUserSettings({...self, isOnboarded}) - self.isOnboarded = isOnboarded - - log.info('Onboarded new device', {isOnboarded}, 'setIsOnboarded') + self.isOnboarded = isOnboarded }, setIsLocalBackupOn: (isLocalBackupOn: boolean) => { Database.updateUserSettings({...self, isLocalBackupOn}) - self.isLocalBackupOn = isLocalBackupOn - - log.info('Local backup is turned on', {isLocalBackupOn}, 'setIsLocalBackupOn') + self.isLocalBackupOn = isLocalBackupOn return isLocalBackupOn }, setIsStorageEncrypted: flow(function* setIsStorageEncryptedvalue( @@ -67,18 +71,24 @@ export const UserSettingsStoreModel = types ) { const isEncrypted = yield MMKVStorage.recryptStorage() Database.updateUserSettings({...self, isStorageEncrypted: isEncrypted}) - self.isStorageEncrypted = isEncrypted - - log.info('Storage encryption changed to', {isEncrypted: value}, 'setIsStorageEncrypted') + self.isStorageEncrypted = isEncrypted return isEncrypted }), setIsTorDaemonOn: (isTorDaemonOn: boolean) => { Database.updateUserSettings({...self, isTorDaemonOn}) - self.isTorDaemonOn = isTorDaemonOn - - log.info('Tor daemon is turned on', {isTorDaemonOn}, 'setIsTorDaemonOn') + self.isTorDaemonOn = isTorDaemonOn return isTorDaemonOn }, + setIsLoggerOn: (isLoggerOn: boolean) => { + Database.updateUserSettings({...self, isLoggerOn}) + self.isLoggerOn = isLoggerOn + return isLoggerOn + }, + setLogLevel: (logLevel: LogLevel) => { + Database.updateUserSettings({...self, logLevel}) + self.logLevel = logLevel + return logLevel + }, })) .views(self => ({ get isUserOnboarded() { diff --git a/src/models/WalletProfileStore.ts b/src/models/WalletProfileStore.ts index d9d6cfff..49a31ab6 100644 --- a/src/models/WalletProfileStore.ts +++ b/src/models/WalletProfileStore.ts @@ -1,6 +1,6 @@ import {Instance, SnapshotOut, types, flow} from 'mobx-state-tree' import {MinibitsClient, NostrClient, NostrUnsignedEvent, Wallet} from '../services' -import {log} from '../utils/logger' +import {log} from '../services/logService' import { getRootStore } from './helpers/getRootStore' @@ -64,7 +64,7 @@ export const WalletProfileStoreModel = types const relaysToPublish: string[] = relaysStore.allUrls - log.trace('relaysToPublish', {relaysToPublish},'publishToRelays') + log.debug('[publishToRelays]', 'Publish profile to relays', {profileEvent, relaysToPublish}) const publishedEvent: Event | undefined = yield NostrClient.publish( profileEvent, @@ -93,7 +93,7 @@ export const WalletProfileStoreModel = types const publishedEvent = yield self.publishToRelays() - log.trace('Wallet profile saved in WalletProfileStore', {self, publishedEvent}) + log.info('[create]', 'Wallet profile saved in WalletProfileStore', {self, publishedEvent}) return self }), updateName: flow(function* update(name: string) { @@ -109,7 +109,7 @@ export const WalletProfileStoreModel = types self.nip05 = profileRecord.nip05 const publishedEvent = yield self.publishToRelays() - log.trace('Wallet name updated in the WalletProfileStore', {self, publishedEvent}) + log.debug('[updateName]', 'Wallet name updated in the WalletProfileStore', {self, publishedEvent}) return self }), updatePicture: flow(function* update(picture: string) { @@ -125,7 +125,7 @@ export const WalletProfileStoreModel = types const publishedEvent = yield self.publishToRelays() - log.trace('Wallet picture updated in the WalletProfileStore', {self, publishedEvent}) + log.debug('[updatePicture]', 'Wallet picture updated in the WalletProfileStore', {self, publishedEvent}) return self }), updateNip05: flow(function* update(newPubkey: string, nip05: string, name: string, picture: string, isOwnProfile: boolean) { @@ -148,7 +148,7 @@ export const WalletProfileStoreModel = types // do not publish to relay as this is external - log.trace('Wallet nip05 updated in the WalletProfileStore', {self}) + log.info('[updateNip05]', 'Wallet nip05 updated in the WalletProfileStore', {self}) return self }), setNip05(nip05: string) { // used in migration to v3 model diff --git a/src/models/helpers/setupRootStore.ts b/src/models/helpers/setupRootStore.ts index b4390de7..e4875d24 100644 --- a/src/models/helpers/setupRootStore.ts +++ b/src/models/helpers/setupRootStore.ts @@ -19,12 +19,11 @@ import RNExitApp from 'react-native-exit-app' import type {RootStore} from '../RootStore' import {MMKVStorage, NostrClient} from '../../services' import {Database} from '../../services' -import { log } from '../../utils/logger' +import { log } from '../../services/logService' import { rootStoreModelVersion } from '../RootStore' import AppError, { Err } from '../../utils/AppError' -import { MINIBITS_NIP05_DOMAIN, MINIBITS_RELAY_URL } from '@env' -import { WalletProfileStoreModel } from '../WalletProfileStore' -import useIsInternetReachable from '../../utils/useIsInternetReachable' +import { MINIBITS_NIP05_DOMAIN } from '@env' +import { LogLevel } from '../../services/log/logTypes' /** * The key we'll be saving our state as within storage. @@ -87,7 +86,7 @@ export async function setupRootStore(rootStore: RootStore) { // run migrations if needed, needs to be after onSnapshot to be persisted try { - log.trace('Device rootStorage version', rootStore.version, 'setupRootStore') + log.debug('[setupRootStore]', `Device rootStore.version is: ${rootStore.version}`) if(rootStore.version < rootStoreModelVersion) { await _runMigrations(rootStore) @@ -149,8 +148,15 @@ async function _runMigrations(rootStore: RootStore) { log.info(`Completed rootStore migrations to the version v${rootStoreModelVersion}`) } + if(currentVersion < 6) { + log.trace(`Starting rootStore migrations from version v${currentVersion} -> v6`) + userSettingsStore.setLogLevel(LogLevel.ERROR) + log.info(`Completed rootStore migrations to the version v${rootStoreModelVersion}`) + } + rootStore.setVersion(rootStoreModelVersion) + } catch (e: any) { throw new AppError( Err.STORAGE_ERROR, @@ -159,54 +165,3 @@ async function _runMigrations(rootStore: RootStore) { ) } } - -/* interface StoreConfig { storageKey: string, store: any } - -let _disposers: IDisposer[] = [] -export async function setupRootStore(rootStore: RootStore) { - - - const storeConfigs: StoreConfig[] = [ - { storageKey: "mintsStore", store: rootStore.mintsStore }, - - { storageKey: "transactionsStore", store: rootStore.transactionsStore }, - ] - - const restoredStates: { [key: string]: any } = {} - - try { - // retrieve key asynchronously - const encryptionKey = await MMKVStorage.getOrCreateMMKVEncryptionKey() - - // initialize or reuse storage with encryption key so we can work in synchronous mode - MMKVStorage.getInstance(encryptionKey) - - for (const { storageKey, store } of storeConfigs) { - const restoredState = (MMKVStorage.load(storageKey)) || {} - applySnapshot(store, restoredState) - restoredStates[storageKey] = restoredState - } - } catch (e: any) { - // if there's any problems loading, then inform the dev what happened - if (__DEV__) { - console.error(e.message, null) - } - } - - // stop tracking state changes if we've already setup - _disposers.forEach(disposer => disposer) - _disposers = [] - - // track changes & save to AsyncStorage for each store - for (const { storageKey, store } of storeConfigs) { - const disposer = onSnapshot(store, (snapshot) => MMKVStorage.save(storageKey, snapshot)) - _disposers.push(disposer) - } - - const unsubscribe = () => { - _disposers.forEach(disposer => disposer()) - _disposers = [] - } - - return { rootStore, restoredStates, unsubscribe } -} */ diff --git a/src/navigation/TabsNavigator.tsx b/src/navigation/TabsNavigator.tsx index 9b9b95bc..b754e752 100644 --- a/src/navigation/TabsNavigator.tsx +++ b/src/navigation/TabsNavigator.tsx @@ -23,7 +23,7 @@ import { MintsScreen, DeveloperScreen, SecurityScreen, - // PrivacyScreen, + PrivacyScreen, UpdateScreen, BackupScreen, LocalRecoveryScreen, @@ -204,7 +204,7 @@ export type SettingsStackParamList = { Settings: undefined Mints: {scannedMintUrl? : string} Security: undefined - // Privacy: undefined + Privacy: undefined Update: { isUpdateAvailable : boolean, isNativeUpdateAvailable: boolean, @@ -237,7 +237,7 @@ const SettingsNavigator = function SettingsNavigator() { - {/**/} + diff --git a/src/screens/Contacts/OwnName.tsx b/src/screens/Contacts/OwnName.tsx index 02c7c585..a1e34bfb 100644 --- a/src/screens/Contacts/OwnName.tsx +++ b/src/screens/Contacts/OwnName.tsx @@ -6,7 +6,7 @@ import {BottomModal, Button, Card, ErrorModal, Icon, InfoModal, ListItem, Loadin import {useStores} from '../../models' import { MinibitsClient} from '../../services' import AppError, { Err } from '../../utils/AppError' -import {log} from '../../utils/logger' +import {log} from '../../services/logService' import { TransactionStatus } from '../../models/Transaction' import { poller, stopPolling } from '../../utils/poller' import QRCode from 'react-native-qrcode-svg' diff --git a/src/screens/Contacts/PrivateContacts.tsx b/src/screens/Contacts/PrivateContacts.tsx index c4cbc85d..9d4a695a 100644 --- a/src/screens/Contacts/PrivateContacts.tsx +++ b/src/screens/Contacts/PrivateContacts.tsx @@ -9,7 +9,7 @@ import {ContactsStackParamList} from '../../navigation' import { MinibitsClient, NostrClient, NostrProfile } from '../../services' import AppError, { Err } from '../../utils/AppError' import {MINIBITS_NIP05_DOMAIN} from '@env' -import { log } from '../../utils/logger' +import { log } from '../../services/logService' import { ContactListItem } from './ContactListItem' import { Contact, ContactType } from '../../models/Contact' import { StackNavigationProp } from '@react-navigation/stack' diff --git a/src/screens/Contacts/PublicContacts.tsx b/src/screens/Contacts/PublicContacts.tsx index cf45d3a0..6acfc4fa 100644 --- a/src/screens/Contacts/PublicContacts.tsx +++ b/src/screens/Contacts/PublicContacts.tsx @@ -8,7 +8,7 @@ import {BottomModal, Button, Card, ErrorModal, Icon, InfoModal, ListItem, Loadin import {useStores} from '../../models' import {NostrClient, NostrEvent, NostrFilter, NostrProfile} from '../../services' import AppError, { Err } from '../../utils/AppError' -import { log } from '../../utils/logger' +import { log } from '../../services/logService' import { Contact, ContactType } from '../../models/Contact' import { StackNavigationProp } from '@react-navigation/stack' import { ContactsStackParamList } from '../../navigation' diff --git a/src/screens/ContactsScreen.tsx b/src/screens/ContactsScreen.tsx index 822f5808..3a5c7af2 100644 --- a/src/screens/ContactsScreen.tsx +++ b/src/screens/ContactsScreen.tsx @@ -9,7 +9,7 @@ import {ContactsStackScreenProps} from '../navigation' import { NostrClient, NostrUnsignedEvent } from '../services' import { PrivateContacts } from './Contacts/PrivateContacts' import { PublicContacts } from './Contacts/PublicContacts' -import { log } from '../utils/logger' +import { log } from '../services/logService' import { getImageSource } from '../utils/utils' import { MINIBITS_NIP05_DOMAIN } from '@env' import { ReceiveOption } from './ReceiveOptionsScreen' diff --git a/src/screens/DeveloperScreen.tsx b/src/screens/DeveloperScreen.tsx index 76812213..fa0ac3f4 100644 --- a/src/screens/DeveloperScreen.tsx +++ b/src/screens/DeveloperScreen.tsx @@ -4,9 +4,7 @@ import {Alert, TextStyle, View, ViewStyle} from 'react-native' import {colors, spacing, useThemeColor} from '../theme' import {SettingsStackScreenProps} from '../navigation' import { - APP_ENV, - LOG_LEVEL, - SENTRY_ACTIVE, + APP_ENV, NATIVE_VERSION_ANDROID, JS_BUNDLE_VERSION, COMMIT, @@ -21,6 +19,8 @@ import { Loading, ErrorModal, InfoModal, + BottomModal, + Button, } from '../components' import {useHeader} from '../utils/useHeader' import {useStores} from '../models' @@ -29,7 +29,7 @@ import AppError from '../utils/AppError' import {Database, KeyChain, NostrClient} from '../services' import {MMKVStorage} from '../services' import {maxTransactionsInModel} from '../models/TransactionsStore' -import { log } from '../utils/logger' +import { LogLevel } from '../services/log/logTypes' export const DeveloperScreen: FC> = observer(function DeveloperScreen(_props) { const {navigation} = _props @@ -42,6 +42,8 @@ export const DeveloperScreen: FC> = observ const [isLoading, setIsLoading] = useState(false) const [rnVersion, setRnVersion] = useState('') + const [isLogLevelSelectorVisible, setIsLogLevelSelectorVisible] = useState(false) + const [selectedLogLevel, setSelectedLogLevel] = useState(userSettingsStore.logLevel) const [error, setError] = useState() const [info, setInfo] = useState('') @@ -84,6 +86,22 @@ export const DeveloperScreen: FC> = observ } } + + const toggleLogLevelSelector = () => + setIsLogLevelSelectorVisible(previousState => !previousState) + + + const onLogLevelSelect = function (logLevel: LogLevel) { + try { + const result = userSettingsStore.setLogLevel(logLevel) + setSelectedLogLevel(result) + } catch (e: any) { + handleError(e) + } + + } + + const factoryReset = async function () { Alert.alert( 'Confirmation', @@ -128,6 +146,8 @@ export const DeveloperScreen: FC> = observ } const headerBg = useThemeColor('header') + const iconSelectedColor = useThemeColor('button') + const iconColor = useThemeColor('textDim') return ( @@ -143,43 +163,36 @@ export const DeveloperScreen: FC> = observ style={$card} HeadingComponent={ <> + } + style={$item} + bottomSeparator={true} + onPress={toggleLogLevelSelector} + /> } style={$item} bottomSeparator={true} onPress={syncTransactionsFromDb} /> - } - style={$item} - /> } style={$item} @@ -189,6 +202,26 @@ Sentry id: ${userSettingsStore.userSettings.walletId} } /> + } + style={$item} + /> + } + /> + + onLogLevelSelect(LogLevel.ERROR)} + style={{paddingHorizontal: spacing.small}} + bottomSeparator={true} + /> + onLogLevelSelect(LogLevel.INFO)} + style={{paddingHorizontal: spacing.small}} + bottomSeparator={true} + /> + onLogLevelSelect(LogLevel.DEBUG)} + style={{paddingHorizontal: spacing.small}} + bottomSeparator={true} + /> + +