@@ -300,6 +300,67 @@ export const checkRgsHealth = async (): Promise<
300300 }
301301} ;
302302
303+ /**
304+ * Checks if the network graph needs to be refreshed before making a payment.
305+ * Considers the graph stale if RGS data is older than the specified threshold.
306+ * @param {number } maxAgeHours - Maximum acceptable age in hours (default: 6)
307+ * @returns {Promise<boolean> } - True if refresh is needed
308+ */
309+ export const shouldRefreshNetworkGraph = async (
310+ maxAgeHours : number = 6 ,
311+ ) : Promise < boolean > => {
312+ const healthCheck = await checkRgsHealth ( ) ;
313+
314+ if ( healthCheck . isErr ( ) ) {
315+ // If we can't check RGS health, assume refresh is needed
316+ console . warn (
317+ `Network graph health check failed: ${ healthCheck . error . message } ` ,
318+ ) ;
319+ return true ;
320+ }
321+
322+ const { ageHours } = healthCheck . value ;
323+
324+ if ( ageHours > maxAgeHours ) {
325+ console . log (
326+ `Network graph is stale (${ ageHours . toFixed ( 1 ) } h old), refresh needed` ,
327+ ) ;
328+ return true ;
329+ }
330+
331+ return false ;
332+ } ;
333+
334+ /**
335+ * Forces a network graph refresh by calling syncLdk.
336+ * This ensures we have the latest routing information before attempting payments.
337+ * @returns {Promise<Result<string>> }
338+ */
339+ export const forceNetworkGraphRefresh = async ( ) : Promise < Result < string > > => {
340+ try {
341+ console . log ( 'Forcing network graph refresh for payment routing...' ) ;
342+
343+ // Sync LDK to get latest network graph
344+ const syncResult = await lm . syncLdk ( ) ;
345+ if ( syncResult . isErr ( ) ) {
346+ return err ( `Network graph refresh failed: ${ syncResult . error . message } ` ) ;
347+ }
348+
349+ // Optionally download fresh scorer data
350+ const scorerResult = await ldk . downloadScorer ( ) ;
351+ if ( scorerResult . isErr ( ) ) {
352+ console . warn (
353+ `Scorer download failed: ${ scorerResult . error . message } , continuing with cached scorer` ,
354+ ) ;
355+ }
356+
357+ console . log ( 'Network graph refresh completed successfully' ) ;
358+ return ok ( 'Network graph refreshed' ) ;
359+ } catch ( e ) {
360+ return err ( `Network graph refresh error: ${ e . message } ` ) ;
361+ }
362+ } ;
363+
303364/**
304365 * Fetch fees from mempool.space and blocktank.to, prioritizing mempool.space.
305366 * Multiple attempts are made to fetch the fees from each provider
@@ -1702,6 +1763,17 @@ export const payLightningInvoice = async ({
17021763 try {
17031764 await waitForLdkChannels ( ) ;
17041765
1766+ // Check if network graph needs refresh before attempting payment
1767+ const needsRefresh = await shouldRefreshNetworkGraph ( 6 ) ; // 6 hour threshold
1768+ if ( needsRefresh ) {
1769+ console . log ( 'Network graph is stale, forcing refresh before payment...' ) ;
1770+ const refreshResult = await forceNetworkGraphRefresh ( ) ;
1771+ if ( refreshResult . isErr ( ) ) {
1772+ console . warn ( `Failed to refresh network graph: ${ refreshResult . error . message } ` ) ;
1773+ // Continue anyway - better to try with stale data than fail immediately
1774+ }
1775+ }
1776+
17051777 const addPeersResponse = await addPeers ( ) ;
17061778 if ( addPeersResponse . isErr ( ) ) {
17071779 return err ( addPeersResponse . error . message ) ;
0 commit comments