From 5c0389b9797df7a2ecb41796a0818fbea88d8928 Mon Sep 17 00:00:00 2001 From: Evan Kaloudis Date: Mon, 8 Jul 2024 10:51:20 -0400 Subject: [PATCH] Embedded LND: Settings: add Custom fee estimator --- components/TextInput.tsx | 8 ++- locales/en.json | 2 + stores/SettingsStore.ts | 23 ++++++++ utils/LndMobileUtils.ts | 10 +++- views/Settings/EmbeddedNode/Advanced.tsx | 75 ++++++++++++++++++++++-- 5 files changed, 110 insertions(+), 8 deletions(-) diff --git a/components/TextInput.tsx b/components/TextInput.tsx index c7cf001de..728819cc4 100644 --- a/components/TextInput.tsx +++ b/components/TextInput.tsx @@ -33,6 +33,7 @@ interface TextInputProps { onPressIn?: any; right?: number; ref?: React.Ref; + error?: boolean; } const TextInput: React.FC = ( @@ -56,7 +57,8 @@ const TextInput: React.FC = ( suffix, toggleUnits, onPressIn, - right + right, + error }, ref ) => { @@ -125,7 +127,9 @@ const TextInput: React.FC = ( opacity: locked ? 0.8 : 1, ...defaultStyle, ...styles.wrapper, - ...style + ...style, + borderWidth: error ? 1.0 : 0, + borderColor: error ? themeColor('error') : undefined }} > {prefix ? ( diff --git a/locales/en.json b/locales/en.json index 8c535f61b..1ae47c666 100644 --- a/locales/en.json +++ b/locales/en.json @@ -878,6 +878,8 @@ "views.Settings.EmbeddedNode.AdvancedDisasterRecovery.noBackups": "No backups found", "views.Settings.EmbeddedNode.LNDLogs.title": "LND Logs", "views.Settings.EmbeddedNode.LNDLogs.copyLogs": "Copy logs to clipboard", + "views.Settings.EmbeddedNode.feeEstimator": "Fee estimator", + "views.Settings.EmbeddedNode.customFeeEstimator": "Custom fee estimator", "views.Settings.LSP.enableLSP": "Enable Lightning Service Provider (LSP)", "views.Settings.LSP.enableLSP.subtitle": "The LSP will get you connected to the Lightning network by opening up payment channels for you.", "views.Settings.LSP.lspAccessKey": "LSP Access Key (if needed)", diff --git a/stores/SettingsStore.ts b/stores/SettingsStore.ts index f811646f9..bac6b192d 100644 --- a/stores/SettingsStore.ts +++ b/stores/SettingsStore.ts @@ -143,6 +143,8 @@ export interface Settings { recovery: boolean; initialLoad: boolean; embeddedTor: boolean; + feeEstimator: string; + customFeeEstimator: string; // LSP enableLSP: boolean; lspMainnet: string; @@ -202,6 +204,25 @@ export const MEMPOOL_RATES_KEYS = [ } ]; +export const DEFAULT_FEE_ESTIMATOR = + 'https://nodes.lightning.computer/fees/v1/btc-fee-estimates.json'; + +export const FEE_ESTIMATOR_KEYS = [ + { + key: 'lightning.computer', + value: 'https://nodes.lightning.computer/fees/v1/btc-fee-estimates.json' + }, + { + key: 'strike.me', + value: 'https://bitcoinchainfees.strike.me/v1/fee-estimates' + }, + { + key: 'Custom', + translateKey: 'views.Settings.Privacy.BlockExplorer.custom', + value: 'Custom' + } +]; + export const INTERFACE_KEYS = [ { key: 'Embedded LND', value: 'embedded-lnd' }, { key: 'LND (REST)', value: 'lnd' }, @@ -1064,6 +1085,8 @@ export default class SettingsStore { recovery: false, initialLoad: true, embeddedTor: false, + feeEstimator: DEFAULT_FEE_ESTIMATOR, + customFeeEstimator: '', // LSP enableLSP: true, lspMainnet: DEFAULT_LSP_MAINNET, diff --git a/utils/LndMobileUtils.ts b/utils/LndMobileUtils.ts index c726fcf68..2da1a4380 100644 --- a/utils/LndMobileUtils.ts +++ b/utils/LndMobileUtils.ts @@ -26,7 +26,8 @@ import stores from '../stores/Stores'; import { DEFAULT_NEUTRINO_PEERS_MAINNET, SECONDARY_NEUTRINO_PEERS_MAINNET, - DEFAULT_NEUTRINO_PEERS_TESTNET + DEFAULT_NEUTRINO_PEERS_TESTNET, + DEFAULT_FEE_ESTIMATOR } from '../stores/SettingsStore'; import { lnrpc } from '../proto/lightning'; @@ -140,7 +141,12 @@ const writeLndConfig = async ( neutrino.persistfilters=true [fee] - fee.url=https://nodes.lightning.computer/fees/v1/btc-fee-estimates.json + fee.url=${ + stores.settingsStore?.settings?.feeEstimator === 'Custom' + ? stores.settingsStore?.settings?.customFeeEstimator + : stores.settingsStore?.settings?.feeEstimator || + DEFAULT_FEE_ESTIMATOR + } [autopilot] autopilot.active=0 diff --git a/views/Settings/EmbeddedNode/Advanced.tsx b/views/Settings/EmbeddedNode/Advanced.tsx index 988f9693f..0b898de4c 100644 --- a/views/Settings/EmbeddedNode/Advanced.tsx +++ b/views/Settings/EmbeddedNode/Advanced.tsx @@ -6,11 +6,16 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; import { StackNavigationProp } from '@react-navigation/stack'; import Button from '../../../components/Button'; +import DropdownSetting from '../../../components/DropdownSetting'; import Header from '../../../components/Header'; import Screen from '../../../components/Screen'; import Switch from '../../../components/Switch'; +import TextInput from '../../../components/TextInput'; -import SettingsStore from '../../../stores/SettingsStore'; +import SettingsStore, { + DEFAULT_FEE_ESTIMATOR, + FEE_ESTIMATOR_KEYS +} from '../../../stores/SettingsStore'; import { localeString } from '../../../utils/LocaleUtils'; import { restartNeeded } from '../../../utils/RestartUtils'; @@ -29,6 +34,8 @@ interface EmbeddedNodeAdvancedSettingsState { embeddedTor: boolean | undefined; persistentMode: boolean | undefined; compactDb: boolean | undefined; + feeEstimator: string; + customFeeEstimator: string; } const PERSISTENT_KEY = 'persistentServicesEnabled'; @@ -43,7 +50,9 @@ export default class EmbeddedNodeAdvancedSettings extends React.Component< rescan: false, persistentMode: false, embeddedTor: false, - compactDb: false + compactDb: false, + feeEstimator: DEFAULT_FEE_ESTIMATOR, + customFeeEstimator: '' }; async UNSAFE_componentWillMount() { @@ -56,13 +65,22 @@ export default class EmbeddedNodeAdvancedSettings extends React.Component< rescan: settings.rescan, persistentMode: persistentMode === 'true' ? true : false, embeddedTor: settings.embeddedTor, - compactDb: settings.compactDb + compactDb: settings.compactDb, + feeEstimator: settings.feeEstimator || DEFAULT_FEE_ESTIMATOR, + customFeeEstimator: settings.customFeeEstimator || '' }); } render() { const { navigation, SettingsStore } = this.props; - const { rescan, persistentMode, embeddedTor, compactDb } = this.state; + const { + rescan, + persistentMode, + embeddedTor, + compactDb, + feeEstimator, + customFeeEstimator + } = this.state; const { updateSettings, embeddedLndNetwork, settings }: any = SettingsStore; const { bimodalPathfinding } = settings; @@ -82,6 +100,55 @@ export default class EmbeddedNodeAdvancedSettings extends React.Component< navigation={navigation} /> + + { + this.setState({ + feeEstimator: value + }); + await updateSettings({ + feeEstimator: value + }); + restartNeeded(); + }} + values={FEE_ESTIMATOR_KEYS} + /> + + {feeEstimator === 'Custom' && ( + <> + + {localeString( + 'views.Settings.EmbeddedNode.customFeeEstimator' + )} + + { + this.setState({ + customFeeEstimator: text + }); + + await updateSettings({ + customFeeEstimator: text + }); + }} + autoCapitalize="none" + error={!customFeeEstimator} + /> + + )} + +