mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-15 11:59:21 +01:00
Merge branch 'master' into lighningse
This commit is contained in:
commit
f4125cb1e9
5 changed files with 204 additions and 109 deletions
|
@ -138,31 +138,40 @@ async function _getRealm() {
|
|||
}
|
||||
|
||||
export const getPreferredServer = async (): Promise<ElectrumServerItem | undefined> => {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const host = (await DefaultPreference.get(ELECTRUM_HOST)) as string;
|
||||
const tcpPort = await DefaultPreference.get(ELECTRUM_TCP_PORT);
|
||||
const sslPort = await DefaultPreference.get(ELECTRUM_SSL_PORT);
|
||||
try {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const host = (await DefaultPreference.get(ELECTRUM_HOST)) as string;
|
||||
const tcpPort = await DefaultPreference.get(ELECTRUM_TCP_PORT);
|
||||
const sslPort = await DefaultPreference.get(ELECTRUM_SSL_PORT);
|
||||
|
||||
console.log('Getting preferred server:', { host, tcpPort, sslPort });
|
||||
console.log('Getting preferred server:', { host, tcpPort, sslPort });
|
||||
|
||||
if (!host) {
|
||||
console.warn('Preferred server host is undefined');
|
||||
return;
|
||||
if (!host) {
|
||||
console.warn('Preferred server host is undefined');
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
host,
|
||||
tcp: tcpPort ? Number(tcpPort) : undefined,
|
||||
ssl: sslPort ? Number(sslPort) : undefined,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error in getPreferredServer:', error);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
host,
|
||||
tcp: tcpPort ? Number(tcpPort) : undefined,
|
||||
ssl: sslPort ? Number(sslPort) : undefined,
|
||||
};
|
||||
};
|
||||
|
||||
export const removePreferredServer = async () => {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
console.log('Removing preferred server');
|
||||
await DefaultPreference.clear(ELECTRUM_HOST);
|
||||
await DefaultPreference.clear(ELECTRUM_TCP_PORT);
|
||||
await DefaultPreference.clear(ELECTRUM_SSL_PORT);
|
||||
try {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
console.log('Removing preferred server');
|
||||
await DefaultPreference.clear(ELECTRUM_HOST);
|
||||
await DefaultPreference.clear(ELECTRUM_TCP_PORT);
|
||||
await DefaultPreference.clear(ELECTRUM_SSL_PORT);
|
||||
} catch (error) {
|
||||
console.error('Error in removePreferredServer:', error);
|
||||
}
|
||||
};
|
||||
|
||||
export async function isDisabled(): Promise<boolean> {
|
||||
|
@ -204,26 +213,31 @@ function getNextPeer() {
|
|||
}
|
||||
|
||||
async function getSavedPeer(): Promise<Peer | null> {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const host = (await DefaultPreference.get(ELECTRUM_HOST)) as string;
|
||||
const tcpPort = await DefaultPreference.get(ELECTRUM_TCP_PORT);
|
||||
const sslPort = await DefaultPreference.get(ELECTRUM_SSL_PORT);
|
||||
try {
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
const host = (await DefaultPreference.get(ELECTRUM_HOST)) as string;
|
||||
const tcpPort = await DefaultPreference.get(ELECTRUM_TCP_PORT);
|
||||
const sslPort = await DefaultPreference.get(ELECTRUM_SSL_PORT);
|
||||
|
||||
console.log('Getting saved peer:', { host, tcpPort, sslPort });
|
||||
console.log('Getting saved peer:', { host, tcpPort, sslPort });
|
||||
|
||||
if (!host) {
|
||||
if (!host) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (sslPort) {
|
||||
return { host, ssl: Number(sslPort) };
|
||||
}
|
||||
|
||||
if (tcpPort) {
|
||||
return { host, tcp: Number(tcpPort) };
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error('Error in getSavedPeer:', error);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (sslPort) {
|
||||
return { host, ssl: Number(sslPort) };
|
||||
}
|
||||
|
||||
if (tcpPort) {
|
||||
return { host, tcp: Number(tcpPort) };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function connectMain(): Promise<void> {
|
||||
|
@ -262,7 +276,8 @@ export async function connectMain(): Promise<void> {
|
|||
// most likely got a timeout from electrum ping. lets reconnect
|
||||
// but only if we were previously connected (mainConnected), otherwise theres other
|
||||
// code which does connection retries
|
||||
mainClient.close();
|
||||
mainClient?.close();
|
||||
mainClient = undefined;
|
||||
mainConnected = false;
|
||||
// dropping `mainConnected` flag ensures there wont be reconnection race condition if several
|
||||
// errors triggered
|
||||
|
@ -310,12 +325,15 @@ export async function connectMain(): Promise<void> {
|
|||
} catch (e) {
|
||||
mainConnected = false;
|
||||
console.log('bad connection:', JSON.stringify(usingPeer), e);
|
||||
mainClient?.close();
|
||||
mainClient = undefined;
|
||||
}
|
||||
|
||||
if (!mainConnected) {
|
||||
console.log('retry');
|
||||
connectionAttempt = connectionAttempt + 1;
|
||||
mainClient.close && mainClient.close();
|
||||
mainClient?.close();
|
||||
mainClient = undefined;
|
||||
if (connectionAttempt >= 5) {
|
||||
presentNetworkErrorAlert(usingPeer);
|
||||
} else {
|
||||
|
@ -407,7 +425,8 @@ const presentNetworkErrorAlert = async (usingPeer?: Peer) => {
|
|||
text: loc.wallets.list_tryagain,
|
||||
onPress: () => {
|
||||
connectionAttempt = 0;
|
||||
mainClient.close() && mainClient.close();
|
||||
mainClient?.close();
|
||||
mainClient = undefined;
|
||||
setTimeout(connectMain, 500);
|
||||
},
|
||||
style: 'default',
|
||||
|
@ -418,7 +437,8 @@ const presentNetworkErrorAlert = async (usingPeer?: Peer) => {
|
|||
presentResetToDefaultsAlert().then(result => {
|
||||
if (result) {
|
||||
connectionAttempt = 0;
|
||||
mainClient.close() && mainClient.close();
|
||||
mainClient?.close();
|
||||
mainClient = undefined;
|
||||
setTimeout(connectMain, 500);
|
||||
}
|
||||
});
|
||||
|
@ -429,7 +449,8 @@ const presentNetworkErrorAlert = async (usingPeer?: Peer) => {
|
|||
text: loc._.cancel,
|
||||
onPress: () => {
|
||||
connectionAttempt = 0;
|
||||
mainClient.close() && mainClient.close();
|
||||
mainClient?.close();
|
||||
mainClient = undefined;
|
||||
},
|
||||
style: 'cancel',
|
||||
},
|
||||
|
@ -474,13 +495,18 @@ async function getRandomDynamicPeer(): Promise<Peer> {
|
|||
}
|
||||
|
||||
export const getBalanceByAddress = async function (address: string): Promise<{ confirmed: number; unconfirmed: number }> {
|
||||
if (!mainClient) throw new Error('Electrum client is not connected');
|
||||
const script = bitcoin.address.toOutputScript(address);
|
||||
const hash = bitcoin.crypto.sha256(script);
|
||||
const reversedHash = Buffer.from(hash).reverse();
|
||||
const balance = await mainClient.blockchainScripthash_getBalance(reversedHash.toString('hex'));
|
||||
balance.addr = address;
|
||||
return balance;
|
||||
try {
|
||||
if (!mainClient) throw new Error('Electrum client is not connected');
|
||||
const script = bitcoin.address.toOutputScript(address);
|
||||
const hash = bitcoin.crypto.sha256(script);
|
||||
const reversedHash = Buffer.from(hash).reverse();
|
||||
const balance = await mainClient.blockchainScripthash_getBalance(reversedHash.toString('hex'));
|
||||
balance.addr = address;
|
||||
return balance;
|
||||
} catch (error) {
|
||||
console.error('Error in getBalanceByAddress:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getConfig = async function () {
|
||||
|
@ -958,25 +984,29 @@ export async function multiGetTransactionByTxid<T extends boolean>(
|
|||
}
|
||||
|
||||
// saving cache:
|
||||
realm.write(() => {
|
||||
for (const txid of Object.keys(ret)) {
|
||||
const tx = ret[txid];
|
||||
// dont cache immature txs, but only for 'verbose', since its fully decoded tx jsons. non-verbose are just plain
|
||||
// strings txhex
|
||||
if (verbose && typeof tx !== 'string' && (!tx?.confirmations || tx.confirmations < 7)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
realm.write(() => {
|
||||
for (const txid of Object.keys(ret)) {
|
||||
const tx = ret[txid];
|
||||
// dont cache immature txs, but only for 'verbose', since its fully decoded tx jsons. non-verbose are just plain
|
||||
// strings txhex
|
||||
if (verbose && typeof tx !== 'string' && (!tx?.confirmations || tx.confirmations < 7)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
realm.create(
|
||||
'Cache',
|
||||
{
|
||||
cache_key: txid + cacheKeySuffix,
|
||||
cache_value: JSON.stringify(ret[txid]),
|
||||
},
|
||||
Realm.UpdateMode.Modified,
|
||||
);
|
||||
}
|
||||
});
|
||||
realm.create(
|
||||
'Cache',
|
||||
{
|
||||
cache_key: txid + cacheKeySuffix,
|
||||
cache_value: JSON.stringify(ret[txid]),
|
||||
},
|
||||
Realm.UpdateMode.Modified,
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (writeError) {
|
||||
console.error('Failed to write transaction cache:', writeError);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { InteractionManager } from 'react-native';
|
||||
import { InteractionManager, LayoutAnimation } from 'react-native';
|
||||
import A from '../../blue_modules/analytics';
|
||||
import { BlueApp as BlueAppClass, LegacyWallet, TCounterpartyMetadata, TTXMetadata, WatchOnlyWallet } from '../../class';
|
||||
import type { TWallet } from '../../class/wallets/types';
|
||||
import presentAlert from '../../components/Alert';
|
||||
import loc from '../../loc';
|
||||
import loc, { formatBalanceWithoutSuffix } from '../../loc';
|
||||
import * as BlueElectrum from '../../blue_modules/BlueElectrum';
|
||||
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
|
||||
import { startAndDecrypt } from '../../blue_modules/start-and-decrypt';
|
||||
import { isNotificationsEnabled, majorTomToGroundControl, unsubscribe } from '../../blue_modules/notifications';
|
||||
import { BitcoinUnit } from '../../models/bitcoinUnits';
|
||||
|
||||
const BlueApp = BlueAppClass.getInstance();
|
||||
|
||||
|
@ -50,6 +51,7 @@ interface StorageContextType {
|
|||
getItem: typeof BlueApp.getItem;
|
||||
setItem: typeof BlueApp.setItem;
|
||||
handleWalletDeletion: (walletID: string, forceDelete?: boolean) => Promise<boolean>;
|
||||
confirmWalletDeletion: (wallet: any, onConfirmed: () => void) => void;
|
||||
}
|
||||
|
||||
export enum WalletTransactionsStatus {
|
||||
|
@ -111,7 +113,7 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) =>
|
|||
|
||||
if (forceDelete) {
|
||||
deleteWallet(wallet);
|
||||
saveToDisk(true);
|
||||
await saveToDisk(true);
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
return true;
|
||||
}
|
||||
|
@ -121,28 +123,35 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) =>
|
|||
isNotificationsSettingsEnabled = await isNotificationsEnabled();
|
||||
} catch (error) {
|
||||
console.error(`handleWalletDeletion: error checking notifications for wallet ${walletID}`, error);
|
||||
presentAlert({
|
||||
title: loc.errors.error,
|
||||
message: loc.wallets.details_delete_wallet_error_message,
|
||||
buttons: [
|
||||
{
|
||||
text: loc.wallets.details_delete_anyway,
|
||||
onPress: async () => await handleWalletDeletion(walletID, true),
|
||||
style: 'destructive',
|
||||
},
|
||||
{
|
||||
text: loc.wallets.list_tryagain,
|
||||
onPress: async () => await handleWalletDeletion(walletID),
|
||||
},
|
||||
{
|
||||
text: loc._.cancel,
|
||||
onPress: () => {},
|
||||
style: 'cancel',
|
||||
},
|
||||
],
|
||||
options: { cancelable: false },
|
||||
return await new Promise<boolean>(resolve => {
|
||||
presentAlert({
|
||||
title: loc.errors.error,
|
||||
message: loc.wallets.details_delete_wallet_error_message,
|
||||
buttons: [
|
||||
{
|
||||
text: loc.wallets.details_delete_anyway,
|
||||
onPress: async () => {
|
||||
const result = await handleWalletDeletion(walletID, true);
|
||||
resolve(result);
|
||||
},
|
||||
style: 'destructive',
|
||||
},
|
||||
{
|
||||
text: loc.wallets.list_tryagain,
|
||||
onPress: async () => {
|
||||
const result = await handleWalletDeletion(walletID);
|
||||
resolve(result);
|
||||
},
|
||||
},
|
||||
{
|
||||
text: loc._.cancel,
|
||||
onPress: () => resolve(false),
|
||||
style: 'cancel',
|
||||
},
|
||||
],
|
||||
options: { cancelable: false },
|
||||
});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -167,41 +176,41 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) =>
|
|||
}
|
||||
deleteWallet(wallet);
|
||||
console.debug(`handleWalletDeletion: wallet ${walletID} deleted successfully`);
|
||||
saveToDisk(true);
|
||||
await saveToDisk(true);
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
return true;
|
||||
} catch (e: unknown) {
|
||||
console.error(`handleWalletDeletion: encountered error for wallet ${walletID}`, e);
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
if (forceDelete) {
|
||||
deleteWallet(wallet);
|
||||
saveToDisk(true);
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
return true;
|
||||
} else {
|
||||
return await new Promise<boolean>(resolve => {
|
||||
presentAlert({
|
||||
title: loc.errors.error,
|
||||
message: loc.wallets.details_delete_wallet_error_message,
|
||||
buttons: [
|
||||
{
|
||||
text: loc.wallets.details_delete_anyway,
|
||||
onPress: async () => await handleWalletDeletion(walletID, true),
|
||||
onPress: async () => {
|
||||
const result = await handleWalletDeletion(walletID, true);
|
||||
resolve(result);
|
||||
},
|
||||
style: 'destructive',
|
||||
},
|
||||
{
|
||||
text: loc.wallets.list_tryagain,
|
||||
onPress: async () => await handleWalletDeletion(walletID),
|
||||
onPress: async () => {
|
||||
const result = await handleWalletDeletion(walletID);
|
||||
resolve(result);
|
||||
},
|
||||
},
|
||||
{
|
||||
text: loc._.cancel,
|
||||
onPress: () => {},
|
||||
onPress: () => resolve(false),
|
||||
style: 'cancel',
|
||||
},
|
||||
],
|
||||
options: { cancelable: false },
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
[deleteWallet, saveToDisk, wallets],
|
||||
|
@ -364,6 +373,36 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) =>
|
|||
[wallets, addWallet, saveToDisk],
|
||||
);
|
||||
|
||||
function confirmWalletDeletion(wallet: any, onConfirmed: () => void) {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationWarning);
|
||||
try {
|
||||
const balance = formatBalanceWithoutSuffix(wallet.getBalance(), BitcoinUnit.SATS, true);
|
||||
presentAlert({
|
||||
title: loc.wallets.details_delete_wallet,
|
||||
message: loc.formatString(loc.wallets.details_del_wb_q, { balance }),
|
||||
buttons: [
|
||||
{
|
||||
text: loc.wallets.details_delete,
|
||||
onPress: () => {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
onConfirmed();
|
||||
},
|
||||
style: 'destructive',
|
||||
},
|
||||
{
|
||||
text: loc._.cancel,
|
||||
onPress: () => {},
|
||||
style: 'cancel',
|
||||
},
|
||||
],
|
||||
options: { cancelable: false },
|
||||
});
|
||||
} catch (error) {
|
||||
// Handle error silently if needed
|
||||
}
|
||||
}
|
||||
|
||||
const value: StorageContextType = useMemo(
|
||||
() => ({
|
||||
wallets,
|
||||
|
@ -400,6 +439,7 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) =>
|
|||
walletTransactionUpdateStatus,
|
||||
setWalletTransactionUpdateStatus,
|
||||
handleWalletDeletion,
|
||||
confirmWalletDeletion,
|
||||
}),
|
||||
[
|
||||
wallets,
|
||||
|
|
16
loc/pl.json
16
loc/pl.json
|
@ -14,6 +14,7 @@
|
|||
"storage_is_encrypted": "Twoje dane są zaszyfrowane. Hasło jest wymagane do ich rozszyfrowania",
|
||||
"yes": "Tak",
|
||||
"no": "Nie",
|
||||
"save": "Zapisz...",
|
||||
"seed": "Seed",
|
||||
"success": "Sukces",
|
||||
"wallet_key": "Klucz Portfela",
|
||||
|
@ -106,7 +107,8 @@
|
|||
"maxSatsFull": "Maksymalna kwota to {max} satoshi lub {currency}",
|
||||
"minSats": "Kwota minimalna to {min} satoshi",
|
||||
"minSatsFull": "Kwota minimalna to {min} satoshi lub {currency}",
|
||||
"qrcode_for_the_address": "Kod QR dla adresu"
|
||||
"qrcode_for_the_address": "Kod QR dla adresu",
|
||||
"bip47_explanation": "Kody płatności to uniwersalne adresy, które chronią prywatność Twojego portfela. Nie wszystkie usługi je obsługują."
|
||||
},
|
||||
"send": {
|
||||
"provided_address_is_invoice": "Ten adres wygląda na fakturę Lightning. Przejdź do swojego portfela Lightning aby ją opłacić.",
|
||||
|
@ -252,7 +254,9 @@
|
|||
"electrum_preferred_server_description": "Wprowadź serwer, którego ma używać twój portfel do wszystkich operacji związanych z Bitcoinem. Po zapisaniu ustawień, portfel będzie korzystał wyłącznie z tego serwera do sprawdzania sald, wysyłania transakcji oraz pobierania danych z sieci. Upewnij się, że masz zaufanie do tego serwera przed jego wyborem.",
|
||||
"electrum_unable_to_connect": "Nie można się połączyć z {server}.",
|
||||
"electrum_history": "Historia",
|
||||
"electrum_reset_to_default": "To pozwoli BlueWallet losowo wybrać serwer z listy.",
|
||||
"electrum_reset": "Ustaw wartości domyślne",
|
||||
"electrum_reset_to_default_and_clear_history": "Przywróć domyślne ustawienia i wyczyść historię",
|
||||
"encrypt_decrypt": "Odszyfruj Magazyn Danych",
|
||||
"encrypt_decrypt_q": "Czy jesteś pewien, że chcesz odszyfrować schowek? To pozwoli na dostęp do twoich portfeli bez hasła.",
|
||||
"encrypt_enc_and_pass": "Szyfrowany i chroniony hasłem",
|
||||
|
@ -488,7 +492,9 @@
|
|||
"identity_pubkey": "Klucz publiczny tożsamości",
|
||||
"xpub_title": "XPUB portfela",
|
||||
"manage_wallets_search_placeholder": "Szukaj portfeli, notatek",
|
||||
"more_info": "Więcej informacji"
|
||||
"more_info": "Więcej informacji",
|
||||
"details_delete_wallet_error_message": "Nie udało się potwierdzić usunięcia tego portfela z powiadomień – możliwe, że przyczyną jest problem z siecią lub słabe połączenie. Jeśli kontynuujesz, możesz nadal otrzymywać powiadomienia o transakcjach związanych z tym portfelem, nawet po jego usunięciu.",
|
||||
"details_delete_anyway": "Usuń mimo to"
|
||||
},
|
||||
"total_balance_view": {
|
||||
"display_in_bitcoin": "Wyświetlaj w Bitcoinie",
|
||||
|
@ -503,6 +509,10 @@
|
|||
"default_label": "Skarbiec wielopodpisowy",
|
||||
"multisig_vault_explain": "Najlepsze bezpieczeństwo dla dużych kwot",
|
||||
"provide_signature": "Podaj podpis",
|
||||
"provide_signature_details": "Użyj urządzenia i portfela, w którym znajduje się klucz, aby podpisać tę transakcję.",
|
||||
"provide_signature_details_bluewallet": "W BlueWallet przejdź do menu ekranu wysyłania i wybierz ",
|
||||
"provide_signature_next_steps": "Skanuj lub importuj podpisaną transakcję",
|
||||
"provide_signature_next_steps_details": "Gdy Twój portfel pomyślnie podpisze transakcję, zeskanuj podany kod QR lub zaimportuj dołączony plik, a następnie zweryfikuj wszystkie szczegóły przed wysłaniem jej.",
|
||||
"vault_key": "Klucz Skarbca {number}",
|
||||
"required_keys_out_of_total": "Wymagane klucze spośród wszystkich",
|
||||
"fee": "Opłata: {number}",
|
||||
|
@ -664,7 +674,7 @@
|
|||
"notification_tx_unconfirmed": "Transakcja powiadomienia nie została jeszcze potwierdzona, proszę czekać",
|
||||
"failed_create_notif_tx": "Nie udało się utworzyć transakcji on-chain",
|
||||
"onchain_tx_needed": "Wymagana transakcja on-chain",
|
||||
"notif_tx_sent": "Transakcja powiadomienia wysłana. Proszę czekać na jej potwierdzenie",
|
||||
"notif_tx_sent" : "Transakcja powiadomienia wysłana. Proszę czekać na jej potwierdzenie",
|
||||
"notif_tx": "Transakcja powiadomienia",
|
||||
"not_found": "Kod płatności nie znaleziony"
|
||||
}
|
||||
|
|
|
@ -173,6 +173,8 @@ const ElectrumSettings: React.FC = () => {
|
|||
const serverSslPort = v?.ssl ? v.ssl.toString() : sslPort?.toString() || '';
|
||||
|
||||
if (serverHost && (serverPort || serverSslPort)) {
|
||||
const testConnect = await BlueElectrum.testConnection(serverHost, Number(serverPort), Number(serverSslPort));
|
||||
if (!testConnect) return;
|
||||
await DefaultPreference.setName(GROUP_IO_BLUEWALLET);
|
||||
|
||||
// Clear current data for the preferred host
|
||||
|
@ -197,6 +199,8 @@ const ElectrumSettings: React.FC = () => {
|
|||
await DefaultPreference.set(BlueElectrum.ELECTRUM_SERVER_HISTORY, JSON.stringify(Array.from(newServerHistory)));
|
||||
setServerHistory(newServerHistory);
|
||||
}
|
||||
} else {
|
||||
throw new Error(loc.settings.electrum_error_connect);
|
||||
}
|
||||
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
|
|
|
@ -89,8 +89,12 @@ const WalletDetails: React.FC = () => {
|
|||
|
||||
const navigateToOverviewAndDeleteWallet = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
await handleWalletDeletion(wallet.getID());
|
||||
popToTop();
|
||||
const deletionSucceeded = await handleWalletDeletion(wallet.getID());
|
||||
if (deletionSucceeded) {
|
||||
popToTop();
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [handleWalletDeletion, wallet]);
|
||||
|
||||
const presentWalletHasBalanceAlert = useCallback(async () => {
|
||||
|
@ -129,10 +133,10 @@ const WalletDetails: React.FC = () => {
|
|||
text: loc.wallets.details_yes_delete,
|
||||
onPress: async () => {
|
||||
const isBiometricsEnabled = await isBiometricUseCapableAndEnabled();
|
||||
|
||||
if (isBiometricsEnabled) {
|
||||
if (!(await unlockWithBiometrics())) {
|
||||
return;
|
||||
setIsLoading(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (wallet.getBalance && wallet.getBalance() > 0 && wallet.allowSend && wallet.allowSend()) {
|
||||
|
@ -143,7 +147,14 @@ const WalletDetails: React.FC = () => {
|
|||
},
|
||||
style: 'destructive',
|
||||
},
|
||||
{ text: loc._.cancel, onPress: () => {}, style: 'cancel' },
|
||||
{
|
||||
text: loc._.cancel,
|
||||
onPress: () => {
|
||||
setIsLoading(false);
|
||||
return false;
|
||||
},
|
||||
style: 'cancel',
|
||||
},
|
||||
],
|
||||
options: { cancelable: false },
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue