Skip to content

fix: orphaned channel recovery pre-startup - #826

Merged
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override
Mar 9, 2026
Merged

fix: orphaned channel recovery pre-startup#826
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override

Conversation

@jvsena42

@jvsena42jvsena42 commented Mar 6, 2026

Copy link
Copy Markdown
Member

Fixes#819

Port of synonymdev/bitkit-ios#480

This PR:
Fixes channel manager override by passing null for orphaned recovery — only monitors are needed for sweeping force-closed channels

Description

When recovering orphaned channel monitors from an RN remote backup, the stale RN channel manager was being passed to LDK alongside the monitors. This overwrites the native app's current channel manager, which can force-close any existing channels the user has opened.

Preview

recover-channel-monitor.webm
counterparty-close.webm

QA Notes

Implement this code to simulate a failure:

 suspend fun retrieveChannelMonitor(channelId: String): ByteArray? = withContext(ioDispatcher) {
runCatching {
throw RuntimeException() //dont commit
  1. Fresh install from RN migration
    • Install RN app, open a channel, backup seed
    • Implement android code to simulate a channel recovery failure
    • Install Android app, restore from seed
    • Verify the channel is force closed
    • Open a new channel
    • Re-runt the android app without the mock code
    • ✅ Verify channel monitor is imported and the new channel is not closed
    • Mine 146 blocks
    • Verify that the swiping transaction is displayed and the balance is updated

OBS: The not can't trigger the ChanelClosed event for the RN closed channel because the old channelManager isn't set anymore, but still can detect the confirmed force-close transaction because it imports the channel monitor. Same behavior on iOS

OBS2: I realized there is not much value on implementing #819 for android because the node is frequently already running from the Foreground Service logic and would have to be restarted anyway

  1. Normal counterparty close channel
    • Use the slack command to close the channel
    • Verify the app displays the closed channel sheet and update the balance

Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
@jvsena42
jvsena42force-pushed the fix/orphaned-channels-override branch from ed8c8a1 to b5da1f0CompareMarch 6, 2026 11:24
@jvsena42
jvsena42 marked this pull request as draft March 6, 2026 12:02
@jvsena42

Copy link
Copy Markdown
MemberAuthor

draft for testing

@jvsena42

Copy link
Copy Markdown
MemberAuthor

after setting channelManager = null the ChannelClose event is not being triggered. I'm still investigating

@jvsena42jvsena42 self-assigned this Mar 8, 2026
@jvsena42
jvsena42 marked this pull request as ready for review March 8, 2026 16:57
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 enabled auto-merge (squash) March 9, 2026 10:06
@jvsena42
jvsena42 requested a review from ovitrifMarch 9, 2026 10:06
@jvsena42jvsena42 modified the milestones: 2.0.1, 2.1.0Mar 9, 2026

@claudeclaudeBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 3 CLAUDE.md compliance issues.

Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 requested a review from pwltrMarch 9, 2026 11:58

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tAck

Tested:

  1. Fresh install from RN migration 🟢
  2. Normal counterparty close 🟢

Two remarks:

  1. Would've been great to create a Closed Channel record in the Lightning Connections screen.
  2. Would've been nice to fix #668 for release 2.1.0
    • Since we're working with milestones now, assigned it the 2.2.0 milestone for next release

@jvsena42
jvsena42 merged commit 3f24993 into masterMar 9, 2026
17 checks passed
@jvsena42
jvsena42 deleted the fix/orphaned-channels-override branch March 9, 2026 18:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move orphaned channel monitor check to pre-setup node

3 participants

@jvsena42@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix: orphaned channel recovery pre-startup by jvsena42 · Pull Request #826 · synonymdev/bitkit-android · GitHub
Skip to content

fix: orphaned channel recovery pre-startup - #826

Merged
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override
Mar 9, 2026
Merged

fix: orphaned channel recovery pre-startup#826
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override

Conversation

@jvsena42

@jvsena42jvsena42 commented Mar 6, 2026

Copy link
Copy Markdown
Member

Fixes#819

Port of synonymdev/bitkit-ios#480

This PR:
Fixes channel manager override by passing null for orphaned recovery — only monitors are needed for sweeping force-closed channels

Description

When recovering orphaned channel monitors from an RN remote backup, the stale RN channel manager was being passed to LDK alongside the monitors. This overwrites the native app's current channel manager, which can force-close any existing channels the user has opened.

Preview

recover-channel-monitor.webm
counterparty-close.webm

QA Notes

Implement this code to simulate a failure:

 suspend fun retrieveChannelMonitor(channelId: String): ByteArray? = withContext(ioDispatcher) {
runCatching {
throw RuntimeException() //dont commit
  1. Fresh install from RN migration
    • Install RN app, open a channel, backup seed
    • Implement android code to simulate a channel recovery failure
    • Install Android app, restore from seed
    • Verify the channel is force closed
    • Open a new channel
    • Re-runt the android app without the mock code
    • ✅ Verify channel monitor is imported and the new channel is not closed
    • Mine 146 blocks
    • Verify that the swiping transaction is displayed and the balance is updated

OBS: The not can't trigger the ChanelClosed event for the RN closed channel because the old channelManager isn't set anymore, but still can detect the confirmed force-close transaction because it imports the channel monitor. Same behavior on iOS

OBS2: I realized there is not much value on implementing #819 for android because the node is frequently already running from the Foreground Service logic and would have to be restarted anyway

  1. Normal counterparty close channel
    • Use the slack command to close the channel
    • Verify the app displays the closed channel sheet and update the balance

Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
@jvsena42
jvsena42force-pushed the fix/orphaned-channels-override branch from ed8c8a1 to b5da1f0CompareMarch 6, 2026 11:24
@jvsena42
jvsena42 marked this pull request as draft March 6, 2026 12:02
@jvsena42

Copy link
Copy Markdown
MemberAuthor

draft for testing

@jvsena42

Copy link
Copy Markdown
MemberAuthor

after setting channelManager = null the ChannelClose event is not being triggered. I'm still investigating

@jvsena42jvsena42 self-assigned this Mar 8, 2026
@jvsena42
jvsena42 marked this pull request as ready for review March 8, 2026 16:57
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 enabled auto-merge (squash) March 9, 2026 10:06
@jvsena42
jvsena42 requested a review from ovitrifMarch 9, 2026 10:06
@jvsena42jvsena42 modified the milestones: 2.0.1, 2.1.0Mar 9, 2026

@claudeclaudeBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 3 CLAUDE.md compliance issues.

Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 requested a review from pwltrMarch 9, 2026 11:58

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tAck

Tested:

  1. Fresh install from RN migration 🟢
  2. Normal counterparty close 🟢

Two remarks:

  1. Would've been great to create a Closed Channel record in the Lightning Connections screen.
  2. Would've been nice to fix #668 for release 2.1.0
    • Since we're working with milestones now, assigned it the 2.2.0 milestone for next release

@jvsena42
jvsena42 merged commit 3f24993 into masterMar 9, 2026
17 checks passed
@jvsena42
jvsena42 deleted the fix/orphaned-channels-override branch March 9, 2026 18:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move orphaned channel monitor check to pre-setup node

3 participants

@jvsena42@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: orphaned channel recovery pre-startup by jvsena42 · Pull Request #826 · synonymdev/bitkit-android · GitHub
Skip to content

fix: orphaned channel recovery pre-startup - #826

Merged
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override
Mar 9, 2026
Merged

fix: orphaned channel recovery pre-startup#826
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override

Conversation

@jvsena42

@jvsena42jvsena42 commented Mar 6, 2026

Copy link
Copy Markdown
Member

Fixes#819

Port of synonymdev/bitkit-ios#480

This PR:
Fixes channel manager override by passing null for orphaned recovery — only monitors are needed for sweeping force-closed channels

Description

When recovering orphaned channel monitors from an RN remote backup, the stale RN channel manager was being passed to LDK alongside the monitors. This overwrites the native app's current channel manager, which can force-close any existing channels the user has opened.

Preview

recover-channel-monitor.webm
counterparty-close.webm

QA Notes

Implement this code to simulate a failure:

 suspend fun retrieveChannelMonitor(channelId: String): ByteArray? = withContext(ioDispatcher) {
runCatching {
throw RuntimeException() //dont commit
  1. Fresh install from RN migration
    • Install RN app, open a channel, backup seed
    • Implement android code to simulate a channel recovery failure
    • Install Android app, restore from seed
    • Verify the channel is force closed
    • Open a new channel
    • Re-runt the android app without the mock code
    • ✅ Verify channel monitor is imported and the new channel is not closed
    • Mine 146 blocks
    • Verify that the swiping transaction is displayed and the balance is updated

OBS: The not can't trigger the ChanelClosed event for the RN closed channel because the old channelManager isn't set anymore, but still can detect the confirmed force-close transaction because it imports the channel monitor. Same behavior on iOS

OBS2: I realized there is not much value on implementing #819 for android because the node is frequently already running from the Foreground Service logic and would have to be restarted anyway

  1. Normal counterparty close channel
    • Use the slack command to close the channel
    • Verify the app displays the closed channel sheet and update the balance

Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
@jvsena42
jvsena42force-pushed the fix/orphaned-channels-override branch from ed8c8a1 to b5da1f0CompareMarch 6, 2026 11:24
@jvsena42
jvsena42 marked this pull request as draft March 6, 2026 12:02
@jvsena42

Copy link
Copy Markdown
MemberAuthor

draft for testing

@jvsena42

Copy link
Copy Markdown
MemberAuthor

after setting channelManager = null the ChannelClose event is not being triggered. I'm still investigating

@jvsena42jvsena42 self-assigned this Mar 8, 2026
@jvsena42
jvsena42 marked this pull request as ready for review March 8, 2026 16:57
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 enabled auto-merge (squash) March 9, 2026 10:06
@jvsena42
jvsena42 requested a review from ovitrifMarch 9, 2026 10:06
@jvsena42jvsena42 modified the milestones: 2.0.1, 2.1.0Mar 9, 2026

@claudeclaudeBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 3 CLAUDE.md compliance issues.

Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 requested a review from pwltrMarch 9, 2026 11:58

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tAck

Tested:

  1. Fresh install from RN migration 🟢
  2. Normal counterparty close 🟢

Two remarks:

  1. Would've been great to create a Closed Channel record in the Lightning Connections screen.
  2. Would've been nice to fix #668 for release 2.1.0
    • Since we're working with milestones now, assigned it the 2.2.0 milestone for next release

@jvsena42
jvsena42 merged commit 3f24993 into masterMar 9, 2026
17 checks passed
@jvsena42
jvsena42 deleted the fix/orphaned-channels-override branch March 9, 2026 18:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move orphaned channel monitor check to pre-setup node

3 participants

@jvsena42@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: orphaned channel recovery pre-startup by jvsena42 · Pull Request #826 · synonymdev/bitkit-android · GitHub
Skip to content

fix: orphaned channel recovery pre-startup - #826

Merged
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override
Mar 9, 2026
Merged

fix: orphaned channel recovery pre-startup#826
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override

Conversation

@jvsena42

@jvsena42jvsena42 commented Mar 6, 2026

Copy link
Copy Markdown
Member

Fixes#819

Port of synonymdev/bitkit-ios#480

This PR:
Fixes channel manager override by passing null for orphaned recovery — only monitors are needed for sweeping force-closed channels

Description

When recovering orphaned channel monitors from an RN remote backup, the stale RN channel manager was being passed to LDK alongside the monitors. This overwrites the native app's current channel manager, which can force-close any existing channels the user has opened.

Preview

recover-channel-monitor.webm
counterparty-close.webm

QA Notes

Implement this code to simulate a failure:

 suspend fun retrieveChannelMonitor(channelId: String): ByteArray? = withContext(ioDispatcher) {
runCatching {
throw RuntimeException() //dont commit
  1. Fresh install from RN migration
    • Install RN app, open a channel, backup seed
    • Implement android code to simulate a channel recovery failure
    • Install Android app, restore from seed
    • Verify the channel is force closed
    • Open a new channel
    • Re-runt the android app without the mock code
    • ✅ Verify channel monitor is imported and the new channel is not closed
    • Mine 146 blocks
    • Verify that the swiping transaction is displayed and the balance is updated

OBS: The not can't trigger the ChanelClosed event for the RN closed channel because the old channelManager isn't set anymore, but still can detect the confirmed force-close transaction because it imports the channel monitor. Same behavior on iOS

OBS2: I realized there is not much value on implementing #819 for android because the node is frequently already running from the Foreground Service logic and would have to be restarted anyway

  1. Normal counterparty close channel
    • Use the slack command to close the channel
    • Verify the app displays the closed channel sheet and update the balance

Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
@jvsena42
jvsena42force-pushed the fix/orphaned-channels-override branch from ed8c8a1 to b5da1f0CompareMarch 6, 2026 11:24
@jvsena42
jvsena42 marked this pull request as draft March 6, 2026 12:02
@jvsena42

Copy link
Copy Markdown
MemberAuthor

draft for testing

@jvsena42

Copy link
Copy Markdown
MemberAuthor

after setting channelManager = null the ChannelClose event is not being triggered. I'm still investigating

@jvsena42jvsena42 self-assigned this Mar 8, 2026
@jvsena42
jvsena42 marked this pull request as ready for review March 8, 2026 16:57
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 enabled auto-merge (squash) March 9, 2026 10:06
@jvsena42
jvsena42 requested a review from ovitrifMarch 9, 2026 10:06
@jvsena42jvsena42 modified the milestones: 2.0.1, 2.1.0Mar 9, 2026

@claudeclaudeBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 3 CLAUDE.md compliance issues.

Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 requested a review from pwltrMarch 9, 2026 11:58

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tAck

Tested:

  1. Fresh install from RN migration 🟢
  2. Normal counterparty close 🟢

Two remarks:

  1. Would've been great to create a Closed Channel record in the Lightning Connections screen.
  2. Would've been nice to fix #668 for release 2.1.0
    • Since we're working with milestones now, assigned it the 2.2.0 milestone for next release

@jvsena42
jvsena42 merged commit 3f24993 into masterMar 9, 2026
17 checks passed
@jvsena42
jvsena42 deleted the fix/orphaned-channels-override branch March 9, 2026 18:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move orphaned channel monitor check to pre-setup node

3 participants

@jvsena42@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix: orphaned channel recovery pre-startup by jvsena42 · Pull Request #826 · synonymdev/bitkit-android · GitHub
Skip to content

fix: orphaned channel recovery pre-startup - #826

Merged
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override
Mar 9, 2026
Merged

fix: orphaned channel recovery pre-startup#826
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override

Conversation

@jvsena42

@jvsena42jvsena42 commented Mar 6, 2026

Copy link
Copy Markdown
Member

Fixes#819

Port of synonymdev/bitkit-ios#480

This PR:
Fixes channel manager override by passing null for orphaned recovery — only monitors are needed for sweeping force-closed channels

Description

When recovering orphaned channel monitors from an RN remote backup, the stale RN channel manager was being passed to LDK alongside the monitors. This overwrites the native app's current channel manager, which can force-close any existing channels the user has opened.

Preview

recover-channel-monitor.webm
counterparty-close.webm

QA Notes

Implement this code to simulate a failure:

 suspend fun retrieveChannelMonitor(channelId: String): ByteArray? = withContext(ioDispatcher) {
runCatching {
throw RuntimeException() //dont commit
  1. Fresh install from RN migration
    • Install RN app, open a channel, backup seed
    • Implement android code to simulate a channel recovery failure
    • Install Android app, restore from seed
    • Verify the channel is force closed
    • Open a new channel
    • Re-runt the android app without the mock code
    • ✅ Verify channel monitor is imported and the new channel is not closed
    • Mine 146 blocks
    • Verify that the swiping transaction is displayed and the balance is updated

OBS: The not can't trigger the ChanelClosed event for the RN closed channel because the old channelManager isn't set anymore, but still can detect the confirmed force-close transaction because it imports the channel monitor. Same behavior on iOS

OBS2: I realized there is not much value on implementing #819 for android because the node is frequently already running from the Foreground Service logic and would have to be restarted anyway

  1. Normal counterparty close channel
    • Use the slack command to close the channel
    • Verify the app displays the closed channel sheet and update the balance

Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
@jvsena42
jvsena42force-pushed the fix/orphaned-channels-override branch from ed8c8a1 to b5da1f0CompareMarch 6, 2026 11:24
@jvsena42
jvsena42 marked this pull request as draft March 6, 2026 12:02
@jvsena42

Copy link
Copy Markdown
MemberAuthor

draft for testing

@jvsena42

Copy link
Copy Markdown
MemberAuthor

after setting channelManager = null the ChannelClose event is not being triggered. I'm still investigating

@jvsena42jvsena42 self-assigned this Mar 8, 2026
@jvsena42
jvsena42 marked this pull request as ready for review March 8, 2026 16:57
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 enabled auto-merge (squash) March 9, 2026 10:06
@jvsena42
jvsena42 requested a review from ovitrifMarch 9, 2026 10:06
@jvsena42jvsena42 modified the milestones: 2.0.1, 2.1.0Mar 9, 2026

@claudeclaudeBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 3 CLAUDE.md compliance issues.

Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 requested a review from pwltrMarch 9, 2026 11:58

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tAck

Tested:

  1. Fresh install from RN migration 🟢
  2. Normal counterparty close 🟢

Two remarks:

  1. Would've been great to create a Closed Channel record in the Lightning Connections screen.
  2. Would've been nice to fix #668 for release 2.1.0
    • Since we're working with milestones now, assigned it the 2.2.0 milestone for next release

@jvsena42
jvsena42 merged commit 3f24993 into masterMar 9, 2026
17 checks passed
@jvsena42
jvsena42 deleted the fix/orphaned-channels-override branch March 9, 2026 18:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move orphaned channel monitor check to pre-setup node

3 participants

@jvsena42@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: orphaned channel recovery pre-startup by jvsena42 · Pull Request #826 · synonymdev/bitkit-android · GitHub
Skip to content

fix: orphaned channel recovery pre-startup - #826

Merged
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override
Mar 9, 2026
Merged

fix: orphaned channel recovery pre-startup#826
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override

Conversation

@jvsena42

@jvsena42jvsena42 commented Mar 6, 2026

Copy link
Copy Markdown
Member

Fixes#819

Port of synonymdev/bitkit-ios#480

This PR:
Fixes channel manager override by passing null for orphaned recovery — only monitors are needed for sweeping force-closed channels

Description

When recovering orphaned channel monitors from an RN remote backup, the stale RN channel manager was being passed to LDK alongside the monitors. This overwrites the native app's current channel manager, which can force-close any existing channels the user has opened.

Preview

recover-channel-monitor.webm
counterparty-close.webm

QA Notes

Implement this code to simulate a failure:

 suspend fun retrieveChannelMonitor(channelId: String): ByteArray? = withContext(ioDispatcher) {
runCatching {
throw RuntimeException() //dont commit
  1. Fresh install from RN migration
    • Install RN app, open a channel, backup seed
    • Implement android code to simulate a channel recovery failure
    • Install Android app, restore from seed
    • Verify the channel is force closed
    • Open a new channel
    • Re-runt the android app without the mock code
    • ✅ Verify channel monitor is imported and the new channel is not closed
    • Mine 146 blocks
    • Verify that the swiping transaction is displayed and the balance is updated

OBS: The not can't trigger the ChanelClosed event for the RN closed channel because the old channelManager isn't set anymore, but still can detect the confirmed force-close transaction because it imports the channel monitor. Same behavior on iOS

OBS2: I realized there is not much value on implementing #819 for android because the node is frequently already running from the Foreground Service logic and would have to be restarted anyway

  1. Normal counterparty close channel
    • Use the slack command to close the channel
    • Verify the app displays the closed channel sheet and update the balance

Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
@jvsena42
jvsena42force-pushed the fix/orphaned-channels-override branch from ed8c8a1 to b5da1f0CompareMarch 6, 2026 11:24
@jvsena42
jvsena42 marked this pull request as draft March 6, 2026 12:02
@jvsena42

Copy link
Copy Markdown
MemberAuthor

draft for testing

@jvsena42

Copy link
Copy Markdown
MemberAuthor

after setting channelManager = null the ChannelClose event is not being triggered. I'm still investigating

@jvsena42jvsena42 self-assigned this Mar 8, 2026
@jvsena42
jvsena42 marked this pull request as ready for review March 8, 2026 16:57
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 enabled auto-merge (squash) March 9, 2026 10:06
@jvsena42
jvsena42 requested a review from ovitrifMarch 9, 2026 10:06
@jvsena42jvsena42 modified the milestones: 2.0.1, 2.1.0Mar 9, 2026

@claudeclaudeBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 3 CLAUDE.md compliance issues.

Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 requested a review from pwltrMarch 9, 2026 11:58

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tAck

Tested:

  1. Fresh install from RN migration 🟢
  2. Normal counterparty close 🟢

Two remarks:

  1. Would've been great to create a Closed Channel record in the Lightning Connections screen.
  2. Would've been nice to fix #668 for release 2.1.0
    • Since we're working with milestones now, assigned it the 2.2.0 milestone for next release

@jvsena42
jvsena42 merged commit 3f24993 into masterMar 9, 2026
17 checks passed
@jvsena42
jvsena42 deleted the fix/orphaned-channels-override branch March 9, 2026 18:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move orphaned channel monitor check to pre-setup node

3 participants

@jvsena42@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: orphaned channel recovery pre-startup by jvsena42 · Pull Request #826 · synonymdev/bitkit-android · GitHub
Skip to content

fix: orphaned channel recovery pre-startup - #826

Merged
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override
Mar 9, 2026
Merged

fix: orphaned channel recovery pre-startup#826
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override

Conversation

@jvsena42

@jvsena42jvsena42 commented Mar 6, 2026

Copy link
Copy Markdown
Member

Fixes#819

Port of synonymdev/bitkit-ios#480

This PR:
Fixes channel manager override by passing null for orphaned recovery — only monitors are needed for sweeping force-closed channels

Description

When recovering orphaned channel monitors from an RN remote backup, the stale RN channel manager was being passed to LDK alongside the monitors. This overwrites the native app's current channel manager, which can force-close any existing channels the user has opened.

Preview

recover-channel-monitor.webm
counterparty-close.webm

QA Notes

Implement this code to simulate a failure:

 suspend fun retrieveChannelMonitor(channelId: String): ByteArray? = withContext(ioDispatcher) {
runCatching {
throw RuntimeException() //dont commit
  1. Fresh install from RN migration
    • Install RN app, open a channel, backup seed
    • Implement android code to simulate a channel recovery failure
    • Install Android app, restore from seed
    • Verify the channel is force closed
    • Open a new channel
    • Re-runt the android app without the mock code
    • ✅ Verify channel monitor is imported and the new channel is not closed
    • Mine 146 blocks
    • Verify that the swiping transaction is displayed and the balance is updated

OBS: The not can't trigger the ChanelClosed event for the RN closed channel because the old channelManager isn't set anymore, but still can detect the confirmed force-close transaction because it imports the channel monitor. Same behavior on iOS

OBS2: I realized there is not much value on implementing #819 for android because the node is frequently already running from the Foreground Service logic and would have to be restarted anyway

  1. Normal counterparty close channel
    • Use the slack command to close the channel
    • Verify the app displays the closed channel sheet and update the balance

Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
@jvsena42
jvsena42force-pushed the fix/orphaned-channels-override branch from ed8c8a1 to b5da1f0CompareMarch 6, 2026 11:24
@jvsena42
jvsena42 marked this pull request as draft March 6, 2026 12:02
@jvsena42

Copy link
Copy Markdown
MemberAuthor

draft for testing

@jvsena42

Copy link
Copy Markdown
MemberAuthor

after setting channelManager = null the ChannelClose event is not being triggered. I'm still investigating

@jvsena42jvsena42 self-assigned this Mar 8, 2026
@jvsena42
jvsena42 marked this pull request as ready for review March 8, 2026 16:57
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 enabled auto-merge (squash) March 9, 2026 10:06
@jvsena42
jvsena42 requested a review from ovitrifMarch 9, 2026 10:06
@jvsena42jvsena42 modified the milestones: 2.0.1, 2.1.0Mar 9, 2026

@claudeclaudeBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 3 CLAUDE.md compliance issues.

Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 requested a review from pwltrMarch 9, 2026 11:58

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tAck

Tested:

  1. Fresh install from RN migration 🟢
  2. Normal counterparty close 🟢

Two remarks:

  1. Would've been great to create a Closed Channel record in the Lightning Connections screen.
  2. Would've been nice to fix #668 for release 2.1.0
    • Since we're working with milestones now, assigned it the 2.2.0 milestone for next release

@jvsena42
jvsena42 merged commit 3f24993 into masterMar 9, 2026
17 checks passed
@jvsena42
jvsena42 deleted the fix/orphaned-channels-override branch March 9, 2026 18:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move orphaned channel monitor check to pre-setup node

3 participants

@jvsena42@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix: orphaned channel recovery pre-startup by jvsena42 · Pull Request #826 · synonymdev/bitkit-android · GitHub
Skip to content

fix: orphaned channel recovery pre-startup - #826

Merged
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override
Mar 9, 2026
Merged

fix: orphaned channel recovery pre-startup#826
jvsena42 merged 9 commits into
masterfrom
fix/orphaned-channels-override

Conversation

@jvsena42

@jvsena42jvsena42 commented Mar 6, 2026

Copy link
Copy Markdown
Member

Fixes#819

Port of synonymdev/bitkit-ios#480

This PR:
Fixes channel manager override by passing null for orphaned recovery — only monitors are needed for sweeping force-closed channels

Description

When recovering orphaned channel monitors from an RN remote backup, the stale RN channel manager was being passed to LDK alongside the monitors. This overwrites the native app's current channel manager, which can force-close any existing channels the user has opened.

Preview

recover-channel-monitor.webm
counterparty-close.webm

QA Notes

Implement this code to simulate a failure:

 suspend fun retrieveChannelMonitor(channelId: String): ByteArray? = withContext(ioDispatcher) {
runCatching {
throw RuntimeException() //dont commit
  1. Fresh install from RN migration
    • Install RN app, open a channel, backup seed
    • Implement android code to simulate a channel recovery failure
    • Install Android app, restore from seed
    • Verify the channel is force closed
    • Open a new channel
    • Re-runt the android app without the mock code
    • ✅ Verify channel monitor is imported and the new channel is not closed
    • Mine 146 blocks
    • Verify that the swiping transaction is displayed and the balance is updated

OBS: The not can't trigger the ChanelClosed event for the RN closed channel because the old channelManager isn't set anymore, but still can detect the confirmed force-close transaction because it imports the channel monitor. Same behavior on iOS

OBS2: I realized there is not much value on implementing #819 for android because the node is frequently already running from the Foreground Service logic and would have to be restarted anyway

  1. Normal counterparty close channel
    • Use the slack command to close the channel
    • Verify the app displays the closed channel sheet and update the balance

Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
@jvsena42
jvsena42force-pushed the fix/orphaned-channels-override branch from ed8c8a1 to b5da1f0CompareMarch 6, 2026 11:24
@jvsena42
jvsena42 marked this pull request as draft March 6, 2026 12:02
@jvsena42

Copy link
Copy Markdown
MemberAuthor

draft for testing

@jvsena42

Copy link
Copy Markdown
MemberAuthor

after setting channelManager = null the ChannelClose event is not being triggered. I'm still investigating

@jvsena42jvsena42 self-assigned this Mar 8, 2026
@jvsena42
jvsena42 marked this pull request as ready for review March 8, 2026 16:57
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 enabled auto-merge (squash) March 9, 2026 10:06
@jvsena42
jvsena42 requested a review from ovitrifMarch 9, 2026 10:06
@jvsena42jvsena42 modified the milestones: 2.0.1, 2.1.0Mar 9, 2026

@claudeclaudeBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 3 CLAUDE.md compliance issues.

Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/services/MigrationService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@jvsena42
jvsena42 requested a review from pwltrMarch 9, 2026 11:58

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tAck

Tested:

  1. Fresh install from RN migration 🟢
  2. Normal counterparty close 🟢

Two remarks:

  1. Would've been great to create a Closed Channel record in the Lightning Connections screen.
  2. Would've been nice to fix #668 for release 2.1.0
    • Since we're working with milestones now, assigned it the 2.2.0 milestone for next release

@jvsena42
jvsena42 merged commit 3f24993 into masterMar 9, 2026
17 checks passed
@jvsena42
jvsena42 deleted the fix/orphaned-channels-override branch March 9, 2026 18:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move orphaned channel monitor check to pre-setup node

3 participants

@jvsena42@ovitrif@piotr-iohk