@@ -2,7 +2,13 @@ import Clipboard from '@react-native-clipboard/clipboard';
22import lm , { ldk } from '@synonymdev/react-native-ldk' ;
33import React , { ReactElement , memo , useState } from 'react' ;
44import { useTranslation } from 'react-i18next' ;
5- import { ScrollView , StyleSheet , TouchableOpacity , View } from 'react-native' ;
5+ import {
6+ Alert ,
7+ ScrollView ,
8+ StyleSheet ,
9+ TouchableOpacity ,
10+ View ,
11+ } from 'react-native' ;
612import RNFS from 'react-native-fs' ;
713import Share from 'react-native-share' ;
814
@@ -53,6 +59,8 @@ const LdkDebug = (): ReactElement => {
5359 const [ rebroadcastingLdk , setRebroadcastingLdk ] = useState ( false ) ;
5460 const [ spendingStuckOutputs , setSpendingStuckOutputs ] = useState ( false ) ;
5561 const [ settingConfirmedTx , setSettingConfirmedTx ] = useState ( false ) ;
62+ const [ runningComprehensiveDebug , setRunningComprehensiveDebug ] =
63+ useState ( false ) ;
5664
5765 const { localBalance, remoteBalance } = useLightningBalance ( ) ;
5866 const selectedWallet = useAppSelector ( selectedWalletSelector ) ;
@@ -446,7 +454,9 @@ const LdkDebug = (): ReactElement => {
446454 showToast ( {
447455 type : 'success' ,
448456 title : 'Transaction Confirmed' ,
449- description : `Transaction ${ txid . slice ( 0 , 8 ) } ... set as confirmed at height ${ tx . status . block_height } ` ,
457+ description : `Transaction ${ txid . slice ( 0 , 8 ) } ... set as confirmed at height ${
458+ tx . status . block_height
459+ } `,
450460 } ) ;
451461 }
452462 } catch ( error ) {
@@ -461,6 +471,116 @@ const LdkDebug = (): ReactElement => {
461471 }
462472 } ;
463473
474+ const sleep = ( ms : number ) =>
475+ new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
476+
477+ const onComprehensiveDebug = async ( ) : Promise < void > => {
478+ Alert . alert (
479+ 'Hard Refresh & Recovery' ,
480+ 'This will perform a hard refresh of LDK and attempt to recover any stuck funds. This can take up to 2 minutes.\n\nPlease keep the app open on this screen until complete.' ,
481+ [
482+ {
483+ text : 'Cancel' ,
484+ style : 'cancel' ,
485+ } ,
486+ {
487+ text : 'Continue' ,
488+ onPress : async ( ) => {
489+ setRunningComprehensiveDebug ( true ) ;
490+ let currentStep = '' ;
491+
492+ try {
493+ // Step 1: Refresh LDK
494+ currentStep = 'Refreshing LDK' ;
495+ showToast ( {
496+ type : 'info' ,
497+ title : 'Step 1/5' ,
498+ description : currentStep ,
499+ } ) ;
500+ await refreshLdk ( { selectedWallet, selectedNetwork } ) ;
501+
502+ await sleep ( 2000 ) ;
503+
504+ // Step 2: Rebroadcast LDK Txs
505+ currentStep = 'Rebroadcasting LDK Transactions' ;
506+ showToast ( {
507+ type : 'info' ,
508+ title : 'Step 2/5' ,
509+ description : currentStep ,
510+ } ) ;
511+ await rebroadcastAllKnownTransactions ( ) ;
512+
513+ await sleep ( 2000 ) ;
514+
515+ // Step 3: Spend Stuck Outputs
516+ currentStep = 'Spending Stuck Outputs' ;
517+ showToast ( {
518+ type : 'info' ,
519+ title : 'Step 3/5' ,
520+ description : currentStep ,
521+ } ) ;
522+ const stuckOutputsRes = await recoverOutputs ( ) ;
523+ if ( stuckOutputsRes . isOk ( ) ) {
524+ showToast ( {
525+ type : 'info' ,
526+ title : 'Stuck Outputs' ,
527+ description : stuckOutputsRes . value ,
528+ } ) ;
529+ }
530+
531+ await sleep ( 2000 ) ;
532+
533+ // Step 4: Spend Outputs from Force Close
534+ currentStep = 'Spending Outputs from Force Close' ;
535+ showToast ( {
536+ type : 'info' ,
537+ title : 'Step 4/5' ,
538+ description : currentStep ,
539+ } ) ;
540+ const forceCloseRes = await recoverOutputsFromForceClose ( ) ;
541+ if ( forceCloseRes . isOk ( ) ) {
542+ showToast ( {
543+ type : 'info' ,
544+ title : 'Force Close Outputs' ,
545+ description : forceCloseRes . value ,
546+ } ) ;
547+ }
548+
549+ await sleep ( 2000 ) ;
550+
551+ // Step 5: Final Refresh LDK
552+ currentStep = 'Final LDK Refresh' ;
553+ showToast ( {
554+ type : 'info' ,
555+ title : 'Step 5/5' ,
556+ description : currentStep ,
557+ } ) ;
558+ await refreshLdk ( { selectedWallet, selectedNetwork } ) ;
559+
560+ // Success
561+ showToast ( {
562+ type : 'success' ,
563+ title : 'Hard Refresh & Recovery Complete' ,
564+ description : 'All operations completed successfully' ,
565+ } ) ;
566+ } catch ( error ) {
567+ showToast ( {
568+ type : 'error' ,
569+ title : `Failed at: ${ currentStep } ` ,
570+ description :
571+ error instanceof Error
572+ ? error . message
573+ : 'Unknown error occurred' ,
574+ } ) ;
575+ } finally {
576+ setRunningComprehensiveDebug ( false ) ;
577+ }
578+ } ,
579+ } ,
580+ ] ,
581+ ) ;
582+ } ;
583+
464584 return (
465585 < ThemedView style = { styles . root } >
466586 < SafeAreaInset type = "top" />
@@ -504,6 +624,7 @@ const LdkDebug = (): ReactElement => {
504624 autoFocus = { false }
505625 value = { txid }
506626 placeholder = "Transaction ID"
627+ blurOnSubmit
507628 returnKeyType = "done"
508629 testID = "TxidInput"
509630 onChangeText = { setTxid }
@@ -521,6 +642,13 @@ const LdkDebug = (): ReactElement => {
521642 < Caption13Up style = { styles . sectionTitle } color = "secondary" >
522643 Debug
523644 </ Caption13Up >
645+ < Button
646+ style = { styles . button }
647+ text = "Hard Refresh & Recovery"
648+ loading = { runningComprehensiveDebug }
649+ testID = "HardRefreshRecovery"
650+ onPress = { onComprehensiveDebug }
651+ />
524652 < Button
525653 style = { styles . button }
526654 text = "Get Node ID"
0 commit comments