Skip to content

Commit

Permalink
REF: storage improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Overtorment committed May 18, 2021
1 parent 59b881b commit 68b2f28
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 78 deletions.
1 change: 1 addition & 0 deletions BlueApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const startAndDecrypt = async retry => {
console.log('App already has some wallets, so we are in already started state, exiting startAndDecrypt');
return true;
}
await BlueApp.migrateKeys();
let password = false;
if (await BlueApp.storageIsEncrypted()) {
do {
Expand Down
41 changes: 25 additions & 16 deletions blue_modules/BlueElectrum.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* global alert */
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Alert } from 'react-native';
import { AppStorage, LegacyWallet, SegwitBech32Wallet, SegwitP2SHWallet } from '../class';
import { LegacyWallet, SegwitBech32Wallet, SegwitP2SHWallet } from '../class';
import DefaultPreference from 'react-native-default-preference';
import RNWidgetCenter from 'react-native-widget-center';
import loc from '../loc';
Expand All @@ -12,6 +12,11 @@ const BigNumber = require('bignumber.js');
const torrific = require('../blue_modules/torrific');
const Realm = require('realm');

const ELECTRUM_HOST = 'electrum_host';
const ELECTRUM_TCP_PORT = 'electrum_tcp_port';
const ELECTRUM_SSL_PORT = 'electrum_ssl_port';
const ELECTRUM_SERVER_HISTORY = 'electrum_server_history';

let _realm;
async function _getRealm() {
if (_realm) return _realm;
Expand Down Expand Up @@ -79,13 +84,13 @@ async function connectMain() {
try {
if (usingPeer.host.endsWith('onion')) {
const randomPeer = await getRandomHardcodedPeer();
await DefaultPreference.set(AppStorage.ELECTRUM_HOST, randomPeer.host);
await DefaultPreference.set(AppStorage.ELECTRUM_TCP_PORT, randomPeer.tcp);
await DefaultPreference.set(AppStorage.ELECTRUM_SSL_PORT, randomPeer.ssl);
await DefaultPreference.set(ELECTRUM_HOST, randomPeer.host);
await DefaultPreference.set(ELECTRUM_TCP_PORT, randomPeer.tcp);
await DefaultPreference.set(ELECTRUM_SSL_PORT, randomPeer.ssl);
} else {
await DefaultPreference.set(AppStorage.ELECTRUM_HOST, usingPeer.host);
await DefaultPreference.set(AppStorage.ELECTRUM_TCP_PORT, usingPeer.tcp);
await DefaultPreference.set(AppStorage.ELECTRUM_SSL_PORT, usingPeer.ssl);
await DefaultPreference.set(ELECTRUM_HOST, usingPeer.host);
await DefaultPreference.set(ELECTRUM_TCP_PORT, usingPeer.tcp);
await DefaultPreference.set(ELECTRUM_SSL_PORT, usingPeer.ssl);
}

RNWidgetCenter.reloadAllTimelines();
Expand Down Expand Up @@ -187,14 +192,14 @@ async function presentNetworkErrorAlert(usingPeer) {
text: loc._.ok,
style: 'destructive',
onPress: async () => {
await AsyncStorage.setItem(AppStorage.ELECTRUM_HOST, '');
await AsyncStorage.setItem(AppStorage.ELECTRUM_TCP_PORT, '');
await AsyncStorage.setItem(AppStorage.ELECTRUM_SSL_PORT, '');
await AsyncStorage.setItem(ELECTRUM_HOST, '');
await AsyncStorage.setItem(ELECTRUM_TCP_PORT, '');
await AsyncStorage.setItem(ELECTRUM_SSL_PORT, '');
try {
await DefaultPreference.setName('group.io.bluewallet.bluewallet');
await DefaultPreference.clear(AppStorage.ELECTRUM_HOST);
await DefaultPreference.clear(AppStorage.ELECTRUM_SSL_PORT);
await DefaultPreference.clear(AppStorage.ELECTRUM_TCP_PORT);
await DefaultPreference.clear(ELECTRUM_HOST);
await DefaultPreference.clear(ELECTRUM_SSL_PORT);
await DefaultPreference.clear(ELECTRUM_TCP_PORT);
RNWidgetCenter.reloadAllTimelines();
} catch (e) {
// Must be running on Android
Expand Down Expand Up @@ -236,9 +241,9 @@ async function getRandomHardcodedPeer() {
}

async function getSavedPeer() {
const host = await AsyncStorage.getItem(AppStorage.ELECTRUM_HOST);
const port = await AsyncStorage.getItem(AppStorage.ELECTRUM_TCP_PORT);
const sslPort = await AsyncStorage.getItem(AppStorage.ELECTRUM_SSL_PORT);
const host = await AsyncStorage.getItem(ELECTRUM_HOST);
const port = await AsyncStorage.getItem(ELECTRUM_TCP_PORT);
const sslPort = await AsyncStorage.getItem(ELECTRUM_SSL_PORT);
return { host, tcp: port, ssl: sslPort };
}

Expand Down Expand Up @@ -845,6 +850,10 @@ module.exports.setBatchingEnabled = () => {

module.exports.hardcodedPeers = hardcodedPeers;
module.exports.getRandomHardcodedPeer = getRandomHardcodedPeer;
module.exports.ELECTRUM_HOST = ELECTRUM_HOST;
module.exports.ELECTRUM_TCP_PORT = ELECTRUM_TCP_PORT;
module.exports.ELECTRUM_SSL_PORT = ELECTRUM_SSL_PORT;
module.exports.ELECTRUM_SERVER_HISTORY = ELECTRUM_SERVER_HISTORY;

const splitIntoChunks = function (arr, chunkSize) {
const groups = [];
Expand Down
18 changes: 11 additions & 7 deletions blue_modules/currency.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import RNWidgetCenter from 'react-native-widget-center';
import * as RNLocalize from 'react-native-localize';
import BigNumber from 'bignumber.js';

import { AppStorage } from '../class';
import { FiatUnit, getFiatRate } from '../models/fiatUnit';

const PREFERRED_CURRENCY = 'preferredCurrency';
const EXCHANGE_RATES = 'currency';

let preferredFiatCurrency = FiatUnit.USD;
const exchangeRates = {};

Expand All @@ -22,15 +24,15 @@ const STRUCT = {
* @returns {Promise<void>}
*/
async function setPrefferedCurrency(item) {
await AsyncStorage.setItem(AppStorage.PREFERRED_CURRENCY, JSON.stringify(item));
await AsyncStorage.setItem(PREFERRED_CURRENCY, JSON.stringify(item));
await DefaultPreference.setName('group.io.bluewallet.bluewallet');
await DefaultPreference.set('preferredCurrency', item.endPointKey);
await DefaultPreference.set('preferredCurrencyLocale', item.locale.replace('-', '_'));
RNWidgetCenter.reloadAllTimelines();
}

async function getPreferredCurrency() {
const preferredCurrency = await JSON.parse(await AsyncStorage.getItem(AppStorage.PREFERRED_CURRENCY));
const preferredCurrency = await JSON.parse(await AsyncStorage.getItem(PREFERRED_CURRENCY));
await DefaultPreference.setName('group.io.bluewallet.bluewallet');
await DefaultPreference.set('preferredCurrency', preferredCurrency.endPointKey);
await DefaultPreference.set('preferredCurrencyLocale', preferredCurrency.locale.replace('-', '_'));
Expand All @@ -44,7 +46,7 @@ async function updateExchangeRate() {
}

try {
preferredFiatCurrency = JSON.parse(await AsyncStorage.getItem(AppStorage.PREFERRED_CURRENCY));
preferredFiatCurrency = JSON.parse(await AsyncStorage.getItem(PREFERRED_CURRENCY));
if (preferredFiatCurrency === null) {
throw Error('No Preferred Fiat selected');
}
Expand All @@ -61,15 +63,15 @@ async function updateExchangeRate() {
try {
rate = await getFiatRate(preferredFiatCurrency.endPointKey);
} catch (Err) {
const lastSavedExchangeRate = JSON.parse(await AsyncStorage.getItem(AppStorage.EXCHANGE_RATES));
const lastSavedExchangeRate = JSON.parse(await AsyncStorage.getItem(EXCHANGE_RATES));
exchangeRates['BTC_' + preferredFiatCurrency.endPointKey] = lastSavedExchangeRate['BTC_' + preferredFiatCurrency.endPointKey] * 1;
return;
}

exchangeRates[STRUCT.LAST_UPDATED] = +new Date();
exchangeRates['BTC_' + preferredFiatCurrency.endPointKey] = rate;
await AsyncStorage.setItem(AppStorage.EXCHANGE_RATES, JSON.stringify(exchangeRates));
await AsyncStorage.setItem(AppStorage.PREFERRED_CURRENCY, JSON.stringify(preferredFiatCurrency));
await AsyncStorage.setItem(EXCHANGE_RATES, JSON.stringify(exchangeRates));
await AsyncStorage.setItem(PREFERRED_CURRENCY, JSON.stringify(preferredFiatCurrency));
await setPrefferedCurrency(preferredFiatCurrency);
}

Expand Down Expand Up @@ -179,3 +181,5 @@ module.exports.btcToSatoshi = btcToSatoshi;
module.exports.getCurrencySymbol = getCurrencySymbol;
module.exports._setPreferredFiatCurrency = _setPreferredFiatCurrency; // export it to mock data in tests
module.exports._setExchangeRate = _setExchangeRate; // export it to mock data in tests
module.exports.PREFERRED_CURRENCY = PREFERRED_CURRENCY;
module.exports.EXCHANGE_RATES = EXCHANGE_RATES;
11 changes: 6 additions & 5 deletions blue_modules/storage-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
import { useAsyncStorage } from '@react-native-async-storage/async-storage';
import React, { createContext, useEffect, useState } from 'react';
import { LayoutAnimation } from 'react-native';
import { AppStorage } from '../class';
import { FiatUnit } from '../models/fiatUnit';
import loc from '../loc';
const BlueApp = require('../BlueApp');
const BlueElectrum = require('./BlueElectrum');
const currency = require('../blue_modules/currency');

const _lastTimeTriedToRefetchWallet = {}; // hashmap of timestamps we _started_ refetching some wallet

Expand All @@ -19,14 +20,14 @@ export const BlueStorageProvider = ({ children }) => {
const [walletsInitialized, setWalletsInitialized] = useState(false);
const [preferredFiatCurrency, _setPreferredFiatCurrency] = useState(FiatUnit.USD);
const [language, _setLanguage] = useState();
const getPreferredCurrencyAsyncStorage = useAsyncStorage(AppStorage.PREFERRED_CURRENCY).getItem;
const getLanguageAsyncStorage = useAsyncStorage(AppStorage.LANG).getItem;
const getPreferredCurrencyAsyncStorage = useAsyncStorage(currency.PREFERRED_CURRENCY).getItem;
const getLanguageAsyncStorage = useAsyncStorage(loc.LANG).getItem;
const [isHandOffUseEnabled, setIsHandOffUseEnabled] = useState(false);
const [isDrawerListBlurred, _setIsDrawerListBlurred] = useState(false);

const setIsHandOffUseEnabledAsyncStorage = value => {
setIsHandOffUseEnabled(value);
return BlueApp.setItem(AppStorage.HANDOFF_STORAGE_KEY, value === true ? '1' : '');
return BlueApp.setIsHandoffEnabled(value);
};

const saveToDisk = async () => {
Expand All @@ -43,7 +44,7 @@ export const BlueStorageProvider = ({ children }) => {
useEffect(() => {
(async () => {
try {
const enabledHandoff = await BlueApp.getItem(AppStorage.HANDOFF_STORAGE_KEY);
const enabledHandoff = await BlueApp.isHandoffEnabled();
setIsHandOffUseEnabled(!!enabledHandoff);
} catch (_e) {
setIsHandOffUseEnabledAsyncStorage(false);
Expand Down
41 changes: 30 additions & 11 deletions class/app-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,36 @@ let usedBucketNum = false;

export class AppStorage {
static FLAG_ENCRYPTED = 'data_encrypted';
static LANG = 'lang';
static EXCHANGE_RATES = 'currency';
static LNDHUB = 'lndhub';
static ELECTRUM_HOST = 'electrum_host';
static ELECTRUM_TCP_PORT = 'electrum_tcp_port';
static ELECTRUM_SSL_PORT = 'electrum_ssl_port';
static ELECTRUM_SERVER_HISTORY = 'electrum_server_history';
static PREFERRED_CURRENCY = 'preferredCurrency';
static ADVANCED_MODE_ENABLED = 'advancedmodeenabled';
static DO_NOT_TRACK = 'donottrack';
static HODL_HODL_API_KEY = 'HODL_HODL_API_KEY';
static HODL_HODL_SIGNATURE_KEY = 'HODL_HODL_SIGNATURE_KEY';
static HODL_HODL_CONTRACTS = 'HODL_HODL_CONTRACTS';
static HANDOFF_STORAGE_KEY = 'HandOff';

static keys2migrate = [AppStorage.HANDOFF_STORAGE_KEY, AppStorage.DO_NOT_TRACK, AppStorage.ADVANCED_MODE_ENABLED];

constructor() {
/** {Array.<AbstractWallet>} */
this.wallets = [];
this.tx_metadata = {};
this.cachedPassword = false;
}

async migrateKeys() {
if (!(typeof navigator !== 'undefined' && navigator.product === 'ReactNative')) return;
for (const key of this.constructor.keys2migrate) {
try {
const value = await RNSecureKeyStore.get(key);
if (value) {
await AsyncStorage.setItem(key, value);
await RNSecureKeyStore.remove(key);
}
} catch (_) {}
}
}

/**
* Wrapper for storage call. Secure store works only in RN environment. AsyncStorage is
* used for cli/tests
Expand Down Expand Up @@ -645,24 +653,35 @@ export class AppStorage {

isAdancedModeEnabled = async () => {
try {
return !!(await this.getItem(AppStorage.ADVANCED_MODE_ENABLED));
return !!(await AsyncStorage.getItem(AppStorage.ADVANCED_MODE_ENABLED));
} catch (_) {}
return false;
};

setIsAdancedModeEnabled = async value => {
await this.setItem(AppStorage.ADVANCED_MODE_ENABLED, value ? '1' : '');
await AsyncStorage.setItem(AppStorage.ADVANCED_MODE_ENABLED, value ? '1' : '');
};

isHandoffEnabled = async () => {
try {
return !!(await AsyncStorage.getItem(AppStorage.HANDOFF_STORAGE_KEY));
} catch (_) {}
return false;
};

setIsHandoffEnabled = async value => {
await AsyncStorage.setItem(AppStorage.HANDOFF_STORAGE_KEY, value ? '1' : '');
};

isDoNotTrackEnabled = async () => {
try {
return !!(await this.getItem(AppStorage.DO_NOT_TRACK));
return !!(await AsyncStorage.getItem(AppStorage.DO_NOT_TRACK));
} catch (_) {}
return false;
};

setDoNotTrack = async value => {
await this.setItem(AppStorage.DO_NOT_TRACK, value ? '1' : '');
await AsyncStorage.setItem(AppStorage.DO_NOT_TRACK, value ? '1' : '');
};

/**
Expand Down
12 changes: 6 additions & 6 deletions class/biometrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import RNSecureKeyStore from 'react-native-secure-key-store';
import loc from '../loc';
import { useContext } from 'react';
import { BlueStorageContext } from '../blue_modules/storage-context';
import * as Sentry from '@sentry/react-native';

function Biometric() {
const { getItem, setItem, setResetOnAppUninstallTo } = useContext(BlueStorageContext);
const { getItem, setItem } = useContext(BlueStorageContext);
Biometric.STORAGEKEY = 'Biometrics';
Biometric.FaceID = 'Face ID';
Biometric.TouchID = 'Touch ID';
Expand Down Expand Up @@ -42,10 +43,9 @@ function Biometric() {
try {
const enabledBiometrics = await getItem(Biometric.STORAGEKEY);
return !!enabledBiometrics;
} catch (_e) {
await setItem(Biometric.STORAGEKEY, '');
return false;
}
} catch (_) {}

return false;
};

Biometric.isBiometricUseCapableAndEnabled = async () => {
Expand All @@ -72,10 +72,10 @@ function Biometric() {
};

Biometric.clearKeychain = async () => {
Sentry.captureMessage('Biometric.clearKeychain()');
await RNSecureKeyStore.remove('data');
await RNSecureKeyStore.remove('data_encrypted');
await RNSecureKeyStore.remove(Biometric.STORAGEKEY);
await setResetOnAppUninstallTo(true);
NavigationService.dispatch(StackActions.replace('WalletsRoot'));
};

Expand Down
9 changes: 5 additions & 4 deletions loc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
import * as RNLocalize from 'react-native-localize';
import BigNumber from 'bignumber.js';

import { AppStorage } from '../class';
import { BitcoinUnit } from '../models/bitcoinUnits';
import { AvailableLanguages } from './languages';
import { I18nManager } from 'react-native';
const currency = require('../blue_modules/currency');

const LANG = 'lang';

dayjs.extend(relativeTime);
dayjs.extend(localizedFormat);

Expand Down Expand Up @@ -158,8 +159,7 @@ const setDateTimeLocale = async () => {

const setLanguageLocale = async () => {
// finding out whether lang preference was saved
// For some reason using the AppStorage.LANG constant is not working. Hard coding string for now.
const lang = await AsyncStorage.getItem('lang');
const lang = await AsyncStorage.getItem(LANG);
if (lang) {
strings.setLanguage(lang);
await setDateTimeLocale();
Expand Down Expand Up @@ -222,7 +222,7 @@ const strings = new Localization({
});

strings.saveLanguage = async lang => {
await AsyncStorage.setItem(AppStorage.LANG, lang);
await AsyncStorage.setItem(LANG, lang);
strings.setLanguage(lang);
await setDateTimeLocale();
};
Expand Down Expand Up @@ -324,4 +324,5 @@ export function _leaveNumbersAndDots(newInputValue) {
return newInputValue;
}

strings.LANG = LANG;
export default strings;
Loading

0 comments on commit 68b2f28

Please sign in to comment.