mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 01:40:12 +01:00
FIX: LNDhub URI invalid after BlueWallet update #7087
This commit is contained in:
parent
dd08d54b01
commit
b5c6c10447
@ -9,6 +9,7 @@ import Realm from 'realm';
|
||||
import { LegacyWallet, SegwitBech32Wallet, SegwitP2SHWallet, TaprootWallet } from '../class';
|
||||
import presentAlert from '../components/Alert';
|
||||
import loc from '../loc';
|
||||
import { GROUP_IO_BLUEWALLET } from './currency';
|
||||
|
||||
const ElectrumClient = require('electrum-client');
|
||||
const net = require('net');
|
||||
@ -200,7 +201,7 @@ export async function connectMain(): Promise<void> {
|
||||
usingPeer = savedPeer;
|
||||
}
|
||||
|
||||
await DefaultPreference.setName('group.io.bluewallet.bluewallet');
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
try {
|
||||
if (usingPeer.host.endsWith('onion')) {
|
||||
const randomPeer = getCurrentPeer();
|
||||
|
@ -24,6 +24,7 @@ import { SegwitP2SHWallet } from './wallets/segwit-p2sh-wallet';
|
||||
import { SLIP39LegacyP2PKHWallet, SLIP39SegwitBech32Wallet, SLIP39SegwitP2SHWallet } from './wallets/slip39-wallets';
|
||||
import { ExtendedTransaction, Transaction, TWallet } from './wallets/types';
|
||||
import { WatchOnlyWallet } from './wallets/watch-only-wallet';
|
||||
import { getLNDHub } from '../helpers/lndHub';
|
||||
|
||||
let usedBucketNum: boolean | number = false;
|
||||
let savingInProgress = 0; // its both a flag and a counter of attempts to write to disk
|
||||
@ -437,7 +438,7 @@ export class BlueApp {
|
||||
unserializedWallet = LightningCustodianWallet.fromJson(key) as unknown as LightningCustodianWallet;
|
||||
let lndhub: false | any = false;
|
||||
try {
|
||||
lndhub = await AsyncStorage.getItem(BlueApp.LNDHUB);
|
||||
lndhub = await getLNDHub();
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
|
@ -579,14 +579,17 @@ export class LightningCustodianWallet extends LegacyWallet {
|
||||
}
|
||||
}
|
||||
|
||||
static async isValidNodeAddress(address: string) {
|
||||
const response = await fetch((address?.endsWith('/') ? address.slice(0, -1) : address) + '/getinfo', {
|
||||
static async isValidNodeAddress(address: string): Promise<boolean> {
|
||||
const normalizedAddress = new URL('/getinfo', address.replace(/([^:]\/)\/+/g, '$1'));
|
||||
|
||||
const response = await fetch(normalizedAddress.toString(), {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
const json = await response.json();
|
||||
if (!json) {
|
||||
throw new Error('API failure: ' + response.statusText);
|
||||
@ -595,6 +598,7 @@ export class LightningCustodianWallet extends LegacyWallet {
|
||||
if (json.code && json.code !== 1) {
|
||||
throw new Error('API error: ' + json.message + ' (code ' + json.code + ')');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
49
helpers/lndHub.ts
Normal file
49
helpers/lndHub.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import { BlueApp } from '../class';
|
||||
import { GROUP_IO_BLUEWALLET } from '..//blue_modules/currency';
|
||||
|
||||
// Function to get the value from DefaultPreference first, then fallback to AsyncStorage
|
||||
// as DefaultPreference uses truly native storage.
|
||||
// If found in AsyncStorage, migrate it to DefaultPreference and remove it from AsyncStorage.
|
||||
export const getLNDHub = async (): Promise<string | undefined> => {
|
||||
try {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
let value = await DefaultPreference.get(BlueApp.LNDHUB);
|
||||
|
||||
// If not found, check AsyncStorage and migrate it to DefaultPreference
|
||||
if (!value) {
|
||||
value = await AsyncStorage.getItem(BlueApp.LNDHUB);
|
||||
|
||||
if (value) {
|
||||
await DefaultPreference.set(BlueApp.LNDHUB, value);
|
||||
await AsyncStorage.removeItem(BlueApp.LNDHUB);
|
||||
console.log('Migrated LNDHub value from AsyncStorage to DefaultPreference');
|
||||
}
|
||||
}
|
||||
|
||||
return value ?? undefined;
|
||||
} catch (error) {
|
||||
console.log('Error getting LNDHub preference:', error);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const setLNDHub = async (value: string): Promise<void> => {
|
||||
try {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
await DefaultPreference.set(BlueApp.LNDHUB, value);
|
||||
} catch (error) {
|
||||
console.log('Error setting LNDHub preference:', error);
|
||||
}
|
||||
};
|
||||
|
||||
export const clearLNDHub = async (): Promise<void> => {
|
||||
try {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
await DefaultPreference.clear(BlueApp.LNDHUB);
|
||||
await AsyncStorage.removeItem(BlueApp.LNDHUB);
|
||||
} catch (error) {
|
||||
console.log('Error clearing LNDHub preference:', error);
|
||||
}
|
||||
};
|
@ -12,7 +12,7 @@ const About = lazy(() => import('../screen/settings/About'));
|
||||
const DefaultView = lazy(() => import('../screen/settings/DefaultView'));
|
||||
const ElectrumSettings = lazy(() => import('../screen/settings/electrumSettings'));
|
||||
const EncryptStorage = lazy(() => import('../screen/settings/EncryptStorage'));
|
||||
const LightningSettings = lazy(() => import('../screen/settings/lightningSettings'));
|
||||
const LightningSettings = lazy(() => import('../screen/settings/LightningSettings'));
|
||||
const NotificationSettings = lazy(() => import('../screen/settings/notificationSettings'));
|
||||
const SelfTest = lazy(() => import('../screen/settings/SelfTest'));
|
||||
const ReleaseNotes = lazy(() => import('../screen/settings/ReleaseNotes'));
|
||||
|
@ -1,18 +1,19 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { RouteProp, useRoute } from '@react-navigation/native';
|
||||
import { Alert, I18nManager, Linking, ScrollView, StyleSheet, TextInput, View } from 'react-native';
|
||||
import { Button as ButtonRNElements } from '@rneui/themed';
|
||||
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import { BlueButtonLink, BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
|
||||
import { BlueApp } from '../../class';
|
||||
import DeeplinkSchemaMatch from '../../class/deeplink-schema-match';
|
||||
import { LightningCustodianWallet } from '../../class/wallets/lightning-custodian-wallet';
|
||||
import presentAlert from '../../components/Alert';
|
||||
import presentAlert, { AlertType } from '../../components/Alert';
|
||||
import { Button } from '../../components/Button';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import { scanQrHelper } from '../../helpers/scan-qr';
|
||||
import loc from '../../loc';
|
||||
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
|
||||
import { GROUP_IO_BLUEWALLET } from '../../blue_modules/currency';
|
||||
import { clearLNDHub, getLNDHub, setLNDHub } from '../../helpers/lndHub';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
uri: {
|
||||
@ -61,28 +62,42 @@ const LightningSettings: React.FC = () => {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
AsyncStorage.getItem(BlueApp.LNDHUB)
|
||||
.then(value => setURI(value ?? undefined))
|
||||
.then(() => setIsLoading(false))
|
||||
.catch(() => setIsLoading(false));
|
||||
const fetchURI = async () => {
|
||||
try {
|
||||
// Try fetching from DefaultPreference first as DefaultPreference uses truly native storage
|
||||
const value = await getLNDHub();
|
||||
setURI(value ?? undefined);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
if (params?.url) {
|
||||
Alert.alert(
|
||||
loc.formatString(loc.settings.set_lndhub_as_default, { url: params.url }) as string,
|
||||
'',
|
||||
[
|
||||
{
|
||||
text: loc._.ok,
|
||||
onPress: () => {
|
||||
params?.url && setLndhubURI(params.url);
|
||||
},
|
||||
style: 'default',
|
||||
},
|
||||
{ text: loc._.cancel, onPress: () => {}, style: 'cancel' },
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
}
|
||||
const initialize = async () => {
|
||||
setIsLoading(true);
|
||||
await fetchURI().finally(() => {
|
||||
setIsLoading(false);
|
||||
if (params?.url) {
|
||||
Alert.alert(
|
||||
loc.formatString(loc.settings.set_lndhub_as_default, { url: params.url }) as string,
|
||||
'',
|
||||
[
|
||||
{
|
||||
text: loc._.ok,
|
||||
onPress: () => {
|
||||
params?.url && setLndhubURI(params.url);
|
||||
},
|
||||
style: 'default',
|
||||
},
|
||||
{ text: loc._.cancel, onPress: () => {}, style: 'cancel' },
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Call the initialize function
|
||||
initialize();
|
||||
}, [params?.url]);
|
||||
|
||||
const setLndhubURI = (value: string) => {
|
||||
@ -91,21 +106,24 @@ const LightningSettings: React.FC = () => {
|
||||
|
||||
setURI(typeof setLndHubUrl === 'string' ? setLndHubUrl.trim() : value.trim());
|
||||
};
|
||||
|
||||
const save = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
if (URI) {
|
||||
await LightningCustodianWallet.isValidNodeAddress(URI);
|
||||
// validating only if its not empty. empty means use default
|
||||
}
|
||||
if (URI) {
|
||||
await AsyncStorage.setItem(BlueApp.LNDHUB, URI);
|
||||
const normalizedURI = new URL(URI.replace(/([^:]\/)\/+/g, '$1')).toString();
|
||||
|
||||
await LightningCustodianWallet.isValidNodeAddress(normalizedURI);
|
||||
|
||||
await setLNDHub(normalizedURI);
|
||||
} else {
|
||||
await AsyncStorage.removeItem(BlueApp.LNDHUB);
|
||||
await clearLNDHub();
|
||||
}
|
||||
presentAlert({ message: loc.settings.lightning_saved });
|
||||
|
||||
presentAlert({ message: loc.settings.lightning_saved, type: AlertType.Toast });
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
} catch (error) {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
presentAlert({ message: loc.settings.lightning_error_lndhub_uri });
|
||||
console.log(error);
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import React, { useCallback, useEffect, useMemo, useReducer } from 'react';
|
||||
import {
|
||||
@ -18,7 +17,7 @@ import {
|
||||
import A from '../../blue_modules/analytics';
|
||||
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
|
||||
import { BlueButtonLink, BlueFormLabel, BlueSpacing20, BlueSpacing40, BlueText } from '../../BlueComponents';
|
||||
import { BlueApp, HDSegwitBech32Wallet, HDSegwitP2SHWallet, LightningCustodianWallet, SegwitP2SHWallet } from '../../class';
|
||||
import { HDSegwitBech32Wallet, HDSegwitP2SHWallet, LightningCustodianWallet, SegwitP2SHWallet } from '../../class';
|
||||
import presentAlert from '../../components/Alert';
|
||||
import Button from '../../components/Button';
|
||||
import { useTheme } from '../../components/themes';
|
||||
@ -30,6 +29,7 @@ import ToolTipMenu from '../../components/TooltipMenu';
|
||||
import { Icon } from '@rneui/themed';
|
||||
import { CommonToolTipActions } from '../../typings/CommonToolTipActions';
|
||||
import { Action } from '../../components/types';
|
||||
import { getLNDHub } from '../../helpers/lndHub';
|
||||
|
||||
enum ButtonSelected {
|
||||
// @ts-ignore: Return later to update
|
||||
@ -261,7 +261,7 @@ const WalletsAdd: React.FC = () => {
|
||||
}, [HeaderRight, colorScheme, colors.foregroundColor, navigateToEntropy, setOptions, toolTipActions]);
|
||||
|
||||
useEffect(() => {
|
||||
AsyncStorage.getItem(BlueApp.LNDHUB)
|
||||
getLNDHub()
|
||||
.then(url => (url ? setWalletBaseURI(url) : setWalletBaseURI('')))
|
||||
.catch(() => setWalletBaseURI(''))
|
||||
.finally(() => setIsLoading(false));
|
||||
|
Loading…
Reference in New Issue
Block a user