mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-18 21:35:21 +01:00
ADD: Toggle for disabling Tor daemon
This commit is contained in:
parent
748c6e4397
commit
78380405aa
@ -4,7 +4,6 @@ import { Alert } from 'react-native';
|
||||
import { LegacyWallet, SegwitBech32Wallet, SegwitP2SHWallet } from '../class';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import loc from '../loc';
|
||||
import { isTorCapable } from './environment';
|
||||
import WidgetCommunication from './WidgetCommunication';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const ElectrumClient = require('electrum-client');
|
||||
@ -18,6 +17,7 @@ const ELECTRUM_TCP_PORT = 'electrum_tcp_port';
|
||||
const ELECTRUM_SSL_PORT = 'electrum_ssl_port';
|
||||
const ELECTRUM_SERVER_HISTORY = 'electrum_server_history';
|
||||
const ELECTRUM_CONNECTION_DISABLED = 'electrum_disabled';
|
||||
const IS_TOR_DAEMON_DISABLED = 'is_tor_daemon_disabled';
|
||||
|
||||
let _realm;
|
||||
async function _getRealm() {
|
||||
@ -90,10 +90,30 @@ async function isDisabled() {
|
||||
return !!isDisabled;
|
||||
}
|
||||
|
||||
async function isTorDaemonDisabled() {
|
||||
let isTorDaemonDisabled;
|
||||
try {
|
||||
const savedValue = await AsyncStorage.getItem(IS_TOR_DAEMON_DISABLED);
|
||||
if (savedValue === null) {
|
||||
isTorDaemonDisabled = false;
|
||||
} else {
|
||||
isTorDaemonDisabled = savedValue;
|
||||
}
|
||||
} catch {
|
||||
isTorDaemonDisabled = true;
|
||||
}
|
||||
|
||||
return !!isTorDaemonDisabled;
|
||||
}
|
||||
|
||||
async function setDisabled(disabled = true) {
|
||||
return AsyncStorage.setItem(ELECTRUM_CONNECTION_DISABLED, disabled ? '1' : '');
|
||||
}
|
||||
|
||||
async function setIsTorDaemonDisabled(disabled = true) {
|
||||
return AsyncStorage.setItem(IS_TOR_DAEMON_DISABLED, disabled ? '1' : '');
|
||||
}
|
||||
|
||||
async function connectMain() {
|
||||
if (await isDisabled()) {
|
||||
console.log('Electrum connection disabled by user. Skipping connectMain call');
|
||||
@ -127,7 +147,7 @@ async function connectMain() {
|
||||
try {
|
||||
console.log('begin connection:', JSON.stringify(usingPeer));
|
||||
mainClient = new ElectrumClient(
|
||||
usingPeer.host.endsWith('.onion') && isTorCapable ? torrific : global.net,
|
||||
usingPeer.host.endsWith('.onion') && !(await isTorDaemonDisabled()) ? torrific : global.net,
|
||||
global.tls,
|
||||
usingPeer.ssl || usingPeer.tcp,
|
||||
usingPeer.host,
|
||||
@ -854,8 +874,9 @@ module.exports.calculateBlockTime = function (height) {
|
||||
* @returns {Promise<boolean>} Whether provided host:port is a valid electrum server
|
||||
*/
|
||||
module.exports.testConnection = async function (host, tcpPort, sslPort) {
|
||||
const isTorDisabled = await isTorDaemonDisabled();
|
||||
const client = new ElectrumClient(
|
||||
host.endsWith('.onion') && isTorCapable ? torrific : global.net,
|
||||
host.endsWith('.onion') && !isTorDisabled ? torrific : global.net,
|
||||
global.tls,
|
||||
sslPort || tcpPort,
|
||||
host,
|
||||
@ -867,7 +888,7 @@ module.exports.testConnection = async function (host, tcpPort, sslPort) {
|
||||
try {
|
||||
const rez = await Promise.race([
|
||||
new Promise(resolve => {
|
||||
timeoutId = setTimeout(() => resolve('timeout'), host.endsWith('.onion') && isTorCapable ? 21000 : 5000);
|
||||
timeoutId = setTimeout(() => resolve('timeout'), host.endsWith('.onion') && !isTorDisabled ? 21000 : 5000);
|
||||
}),
|
||||
client.connect(),
|
||||
]);
|
||||
@ -899,6 +920,8 @@ module.exports.setBatchingEnabled = () => {
|
||||
module.exports.connectMain = connectMain;
|
||||
module.exports.isDisabled = isDisabled;
|
||||
module.exports.setDisabled = setDisabled;
|
||||
module.exports.isTorDaemonDisabled = isTorDaemonDisabled;
|
||||
module.exports.setIsTorDaemonDisabled = setIsTorDaemonDisabled;
|
||||
module.exports.hardcodedPeers = hardcodedPeers;
|
||||
module.exports.getRandomHardcodedPeer = getRandomHardcodedPeer;
|
||||
module.exports.ELECTRUM_HOST = ELECTRUM_HOST;
|
||||
|
@ -23,11 +23,17 @@ export const BlueStorageProvider = ({ children }) => {
|
||||
const getLanguageAsyncStorage = useAsyncStorage(loc.LANG).getItem;
|
||||
const [isHandOffUseEnabled, setIsHandOffUseEnabled] = useState(false);
|
||||
const [isElectrumDisabled, setIsElectrumDisabled] = useState(true);
|
||||
const [isTorDaemonDisabled, setIsTorDaemonDisabled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
BlueElectrum.isDisabled().then(setIsElectrumDisabled);
|
||||
BlueElectrum.isTorDaemonDisabled().then(setIsTorDaemonDisabled);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
BlueElectrum.setIsTorDaemonDisabled(isTorDaemonDisabled);
|
||||
}, [isTorDaemonDisabled]);
|
||||
|
||||
const setIsHandOffUseEnabledAsyncStorage = value => {
|
||||
setIsHandOffUseEnabled(value);
|
||||
return BlueApp.setIsHandoffEnabled(value);
|
||||
@ -234,6 +240,8 @@ export const BlueStorageProvider = ({ children }) => {
|
||||
isDoNotTrackEnabled,
|
||||
isElectrumDisabled,
|
||||
setIsElectrumDisabled,
|
||||
isTorDaemonDisabled,
|
||||
setIsTorDaemonDisabled,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
@ -2,8 +2,8 @@ import { LegacyWallet } from './legacy-wallet';
|
||||
import Frisbee from 'frisbee';
|
||||
import bolt11 from 'bolt11';
|
||||
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
|
||||
import { isTorCapable } from '../../blue_modules/environment';
|
||||
const torrific = require('../../blue_modules/torrific');
|
||||
const BlueElectrum = require('../../blue_modules/BlueElectrum');
|
||||
|
||||
export class LightningCustodianWallet extends LegacyWallet {
|
||||
static type = 'lightningCustodianWallet';
|
||||
@ -72,12 +72,13 @@ export class LightningCustodianWallet extends LegacyWallet {
|
||||
this._api = new Frisbee({
|
||||
baseURI: this.baseURI,
|
||||
});
|
||||
|
||||
if (isTorCapable && this.baseURI && this.baseURI?.indexOf('.onion') !== -1) {
|
||||
this._api = new torrific.Torsbee({
|
||||
baseURI: this.baseURI,
|
||||
});
|
||||
}
|
||||
BlueElectrum.isTorDaemonDisabled().then(isDisabled => {
|
||||
if (!isDisabled && this.baseURI && this.baseURI?.indexOf('.onion') !== -1) {
|
||||
this._api = new torrific.Torsbee({
|
||||
baseURI: this.baseURI,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
accessTokenExpired() {
|
||||
|
@ -267,13 +267,13 @@ PODS:
|
||||
- React-jsinspector (0.64.2)
|
||||
- react-native-blue-crypto (1.0.0):
|
||||
- React
|
||||
- react-native-camera (4.2.0):
|
||||
- react-native-camera (4.2.1):
|
||||
- React-Core
|
||||
- react-native-camera/RCT (= 4.2.0)
|
||||
- react-native-camera/RN (= 4.2.0)
|
||||
- react-native-camera/RCT (4.2.0):
|
||||
- react-native-camera/RCT (= 4.2.1)
|
||||
- react-native-camera/RN (= 4.2.1)
|
||||
- react-native-camera/RCT (4.2.1):
|
||||
- React-Core
|
||||
- react-native-camera/RN (4.2.0):
|
||||
- react-native-camera/RN (4.2.1):
|
||||
- React-Core
|
||||
- react-native-document-picker (3.5.4):
|
||||
- React
|
||||
@ -281,7 +281,7 @@ PODS:
|
||||
- React
|
||||
- react-native-idle-timer (2.1.6):
|
||||
- React-Core
|
||||
- react-native-image-picker (4.0.6):
|
||||
- react-native-image-picker (4.1.1):
|
||||
- React-Core
|
||||
- react-native-ios-context-menu (1.3.0):
|
||||
- React-Core
|
||||
@ -431,7 +431,7 @@ PODS:
|
||||
- React-RCTImage
|
||||
- RNSecureKeyStore (1.0.0):
|
||||
- React
|
||||
- RNShare (7.1.0):
|
||||
- RNShare (7.1.1):
|
||||
- React-Core
|
||||
- RNSVG (12.1.1):
|
||||
- React
|
||||
@ -739,11 +739,11 @@ SPEC CHECKSUMS:
|
||||
React-jsiexecutor: 80c46bd381fd06e418e0d4f53672dc1d1945c4c3
|
||||
React-jsinspector: cc614ec18a9ca96fd275100c16d74d62ee11f0ae
|
||||
react-native-blue-crypto: 23f1558ad3d38d7a2edb7e2f6ed1bc520ed93e56
|
||||
react-native-camera: 384df93277a5ccdc800ca9f86daac7107598365e
|
||||
react-native-camera: 210a872c84d3aa0982a9223047ef9e743ed694fa
|
||||
react-native-document-picker: c5752781fbc0c126c627c1549b037c139444a4cf
|
||||
react-native-fingerprint-scanner: c68136ca57e3704d7bdf5faa554ea535ce15b1d0
|
||||
react-native-idle-timer: 97b8283237d45146a7a5c25bdebe9e1e85f3687b
|
||||
react-native-image-picker: 7bda3c7297c3ea16f4f504ad6174aa7e548192ef
|
||||
react-native-image-picker: 7c37cd600a9b7338ced8609cc3ad108ebe6c444f
|
||||
react-native-ios-context-menu: c787c9a764525d07dff9bd75a191f67de7176e9f
|
||||
react-native-randombytes: 5fc412efe7b5c55b9002c0004d75fe5fabcaa507
|
||||
react-native-safe-area-context: 5cf05f49df9d17261e40e518481f2e334c6cd4b5
|
||||
@ -783,7 +783,7 @@ SPEC CHECKSUMS:
|
||||
RNReanimated: 241c586663f44f19a53883c63375fdd041253960
|
||||
RNScreens: 0591543e343c7444ea1756b6265d81a4295922c9
|
||||
RNSecureKeyStore: f1ad870e53806453039f650720d2845c678d89c8
|
||||
RNShare: 072f63d19c2b90da3742adac614396d805e7ae22
|
||||
RNShare: a22398d8d02336133e28bf8b6e0b47b31abade41
|
||||
RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
|
||||
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
|
||||
RNWatch: 99637948ec9b5c9ec5a41920642594ad5ba07e80
|
||||
|
@ -5,6 +5,7 @@
|
||||
"continue": "Continue",
|
||||
"enter_password": "Enter password",
|
||||
"never": "Never",
|
||||
"disabled": "Disabled",
|
||||
"of": "{number} of {total}",
|
||||
"ok": "OK",
|
||||
"storage_is_encrypted": "Your storage is encrypted. Password is required to decrypt it.",
|
||||
|
12
package-lock.json
generated
12
package-lock.json
generated
@ -19673,9 +19673,9 @@
|
||||
"from": "git+https://github.com/BlueWallet/react-native-blue-crypto.git#fbc2e6beded0b7f61e0986ce98cca1230f84bc1c"
|
||||
},
|
||||
"react-native-camera": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-camera/-/react-native-camera-4.2.0.tgz",
|
||||
"integrity": "sha512-AhBEtkCLXENrjQke42FwiZL3CStugLaxXsJIqx7xYDnSEHnSwM9/dFen6BdNVoh9LiPgAw6X3CjOvvJNoGchhQ==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-camera/-/react-native-camera-4.2.1.tgz",
|
||||
"integrity": "sha512-+Vkql24PFYQfsPRznJCvPwJQfyzCnjlcww/iZ4Ej80bgivKjL9eU0IMQIXp4yi6XCrKi4voWXxIDPMupQZKeIQ==",
|
||||
"requires": {
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
@ -19979,9 +19979,9 @@
|
||||
"from": "git+https://github.com/BlueWallet/react-native-secure-key-store.git#63ab38c9d382a819844a086a69cc204c46aa93f9"
|
||||
},
|
||||
"react-native-share": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-share/-/react-native-share-7.1.0.tgz",
|
||||
"integrity": "sha512-LSnAz2OeuLrR2MS+PLUR3JN67eCkvu9Eh89j6FD2tah0BwJ5U/Vl31CcwJPV17+X6bLftzUxECPHZ9TtEr7Guw=="
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-share/-/react-native-share-7.1.1.tgz",
|
||||
"integrity": "sha512-pdIr+OUmCP5+t0HHSTy5opbBle+dE7Qw98U8ixSaIGoeQbkyP7vnCDpngxQoOHJ4IdcrbGgSAx+m0OAvvACzXg=="
|
||||
},
|
||||
"react-native-size-matters": {
|
||||
"version": "0.3.1",
|
||||
|
@ -28,12 +28,11 @@ import loc, { formatBalanceWithoutSuffix, formatBalancePlain } from '../../loc';
|
||||
import Lnurl from '../../class/lnurl';
|
||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import Notifications from '../../blue_modules/notifications';
|
||||
import { isTorCapable } from '../../blue_modules/environment';
|
||||
const currency = require('../../blue_modules/currency');
|
||||
const torrific = require('../../blue_modules/torrific');
|
||||
|
||||
const LNDCreateInvoice = () => {
|
||||
const { wallets, saveToDisk, setSelectedWallet } = useContext(BlueStorageContext);
|
||||
const { wallets, saveToDisk, setSelectedWallet, isTorDaemonDisabled } = useContext(BlueStorageContext);
|
||||
const { walletID, uri } = useRoute().params;
|
||||
const wallet = useRef(wallets.find(item => item.getID() === walletID) || wallets.find(item => item.chain === Chain.OFFCHAIN));
|
||||
const { name } = useRoute();
|
||||
@ -177,7 +176,7 @@ const LNDCreateInvoice = () => {
|
||||
const callbackUrl = callback + (callback.indexOf('?') !== -1 ? '&' : '?') + 'k1=' + k1 + '&pr=' + invoiceRequest;
|
||||
|
||||
let reply;
|
||||
if (isTorCapable && callbackUrl.includes('.onion')) {
|
||||
if (!isTorDaemonDisabled && callbackUrl.includes('.onion')) {
|
||||
const api = new torrific.Torsbee();
|
||||
const torResponse = await api.get(callbackUrl);
|
||||
reply = torResponse.body;
|
||||
@ -228,7 +227,7 @@ const LNDCreateInvoice = () => {
|
||||
// calling the url
|
||||
let reply;
|
||||
try {
|
||||
if (isTorCapable && url.includes('.onion')) {
|
||||
if (!isTorDaemonDisabled && url.includes('.onion')) {
|
||||
const api = new torrific.Torsbee();
|
||||
const torResponse = await api.get(url);
|
||||
reply = torResponse.body;
|
||||
|
@ -15,7 +15,6 @@ import loc, { formatBalance, formatBalanceWithoutSuffix } from '../../loc';
|
||||
import Notifications from '../../blue_modules/notifications';
|
||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import { Psbt } from 'bitcoinjs-lib';
|
||||
import { isTorCapable } from '../../blue_modules/environment';
|
||||
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
|
||||
const currency = require('../../blue_modules/currency');
|
||||
const BlueElectrum = require('../../blue_modules/BlueElectrum');
|
||||
@ -24,7 +23,7 @@ const bitcoin = require('bitcoinjs-lib');
|
||||
const torrific = require('../../blue_modules/torrific');
|
||||
|
||||
const Confirm = () => {
|
||||
const { wallets, fetchAndSaveWalletTransactions, isElectrumDisabled } = useContext(BlueStorageContext);
|
||||
const { wallets, fetchAndSaveWalletTransactions, isElectrumDisabled, isTorDaemonDisabled } = useContext(BlueStorageContext);
|
||||
const [isBiometricUseCapableAndEnabled, setIsBiometricUseCapableAndEnabled] = useState(false);
|
||||
const { params } = useRoute();
|
||||
const { recipients = [], walletID, fee, memo, tx, satoshiPerByte, psbt } = params;
|
||||
@ -121,7 +120,7 @@ const Confirm = () => {
|
||||
const payJoinWallet = new PayjoinTransaction(psbt, txHex => broadcast(txHex), wallet);
|
||||
const paymentScript = getPaymentScript();
|
||||
let payjoinClient;
|
||||
if (isTorCapable && payjoinUrl.includes('.onion')) {
|
||||
if (!isTorDaemonDisabled && payjoinUrl.includes('.onion')) {
|
||||
console.warn('trying TOR....');
|
||||
// working through TOR - crafting custom requester that will handle TOR http request
|
||||
const customPayjoinRequester = {
|
||||
|
@ -162,10 +162,6 @@ export default class ElectrumSettings extends Component {
|
||||
const sslPort = this.state.sslPort ? this.state.sslPort : '';
|
||||
const serverHistory = this.state.serverHistory || [];
|
||||
|
||||
if (host.endsWith('.onion') && !isTorCapable) {
|
||||
return alert(loc.settings.tor_unsupported);
|
||||
}
|
||||
|
||||
this.setState({ isLoading: true }, async () => {
|
||||
try {
|
||||
if (!host && !port && !sslPort) {
|
||||
|
@ -96,10 +96,6 @@ const LightningSettings: React.FC & { navigationOptions: NavigationOptionsGetter
|
||||
setIsLoading(true);
|
||||
try {
|
||||
if (URI) {
|
||||
if (URI.endsWith('.onion') && !isTorCapable) {
|
||||
setIsLoading(false);
|
||||
return alert(loc.settings.tor_unsupported);
|
||||
}
|
||||
await LightningCustodianWallet.isValidNodeAddress(URI);
|
||||
// validating only if its not empty. empty means use default
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* global alert */
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { View, StyleSheet } from 'react-native';
|
||||
|
||||
import navigationStyle from '../../components/navigationStyle';
|
||||
import { BlueButton, BlueCard, BlueLoading, BlueSpacing20, BlueText, SafeBlueArea } from '../../BlueComponents';
|
||||
import { BlueButton, BlueCard, BlueListItem, BlueLoading, BlueSpacing20, BlueText, SafeBlueArea } from '../../BlueComponents';
|
||||
import loc from '../../loc';
|
||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
|
||||
const torrific = require('../../blue_modules/torrific');
|
||||
|
||||
@ -20,6 +21,7 @@ const styles = StyleSheet.create({
|
||||
const TorSettings = () => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [daemonStatus, setDaemonStatus] = useState('');
|
||||
const { isTorDaemonDisabled, setIsTorDaemonDisabled } = useContext(BlueStorageContext);
|
||||
|
||||
const updateStatus = async () => {
|
||||
const status = await torrific.getDaemonStatus();
|
||||
@ -38,7 +40,7 @@ const TorSettings = () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await torrific.testSocket();
|
||||
alert('OK');
|
||||
alert(loc._.ok);
|
||||
} catch (error) {
|
||||
alert(error.message);
|
||||
} finally {
|
||||
@ -50,7 +52,7 @@ const TorSettings = () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await torrific.testHttp();
|
||||
alert('OK');
|
||||
alert(loc._.ok);
|
||||
} catch (error) {
|
||||
alert(error.message);
|
||||
} finally {
|
||||
@ -60,12 +62,19 @@ const TorSettings = () => {
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(updateStatus, 1000);
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isTorDaemonDisabled) {
|
||||
stopIfRunning();
|
||||
}
|
||||
}, [isTorDaemonDisabled]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<View style={[styles.root]}>
|
||||
@ -76,18 +85,28 @@ const TorSettings = () => {
|
||||
|
||||
return (
|
||||
<SafeBlueArea>
|
||||
<BlueCard>
|
||||
<BlueText>Daemon Status: {daemonStatus}</BlueText>
|
||||
</BlueCard>
|
||||
<BlueCard>
|
||||
<BlueButton title="start" onPress={startIfNotStarted} />
|
||||
<BlueSpacing20 />
|
||||
<BlueButton title="stop" onPress={stopIfRunning} />
|
||||
<BlueSpacing20 />
|
||||
<BlueButton title="test socket" onPress={testSocket} />
|
||||
<BlueSpacing20 />
|
||||
<BlueButton title="test http" onPress={testHttp} />
|
||||
</BlueCard>
|
||||
<BlueListItem
|
||||
hideChevron
|
||||
title={loc._.disabled}
|
||||
Component={View}
|
||||
switch={{ onValueChange: setIsTorDaemonDisabled, value: isTorDaemonDisabled }}
|
||||
/>
|
||||
{!isTorDaemonDisabled && (
|
||||
<>
|
||||
<BlueCard>
|
||||
<BlueText>Daemon Status: {daemonStatus}</BlueText>
|
||||
</BlueCard>
|
||||
<BlueCard>
|
||||
<BlueButton title={loc.send.dynamic_start} onPress={startIfNotStarted} />
|
||||
<BlueSpacing20 />
|
||||
<BlueButton title={loc.send.dynamic_stop} onPress={stopIfRunning} />
|
||||
<BlueSpacing20 />
|
||||
<BlueButton title="Test Socket" onPress={testSocket} />
|
||||
<BlueSpacing20 />
|
||||
<BlueButton title="Test HTTP" onPress={testHttp} />
|
||||
</BlueCard>
|
||||
</>
|
||||
)}
|
||||
</SafeBlueArea>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user