Fix Lightning swap fee estimation, auto-create wallet in 1-click invest flow#776
Merged
dangershony merged 10 commits intomainfrom Apr 22, 2026
Merged
Fix Lightning swap fee estimation, auto-create wallet in 1-click invest flow#776dangershony merged 10 commits intomainfrom
dangershony merged 10 commits intomainfrom
Conversation
The mobile port renamed these AXAML elements (ContinueSpinner -> ContinueBtnSpinner, ContinueText -> ContinueBtnContent) breaking 6 integration tests that look up controls by name. Restore the names expected by TestHelpers and code-behind. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dget The Lightning swap fee estimation used a hardcoded 250 vbyte estimate for the investment transaction, but the actual size is ~252 + (N × 43) vbytes where N is the stage count. For a 4-stage project at 20 sat/vB this meant budgeting 5,000 sats when the real fee was ~8,500 — causing BuildInvestmentDraft to fail with insufficient funds on the funding address. Add StageCount parameter to CreateLightningSwapRequest and compute the estimate from the deterministic transaction structure (1 P2WPKH input, 1 P2WSH angor fee, 1 OP_RETURN, N P2TR stages, 1 P2WPKH change). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…n test Add AutomationProperties.AutomationId to key controls in InvestPageView and InvestModalsView so headless integration tests can find them the same way Appium would — making tests portable to E2E and resilient to ViewModel extraction/refactoring. New test: OneClickInvestOnChainFundedTest exercises the full 1-click invest on-chain flow with real faucet funding. No wallet pre-funding — the faucet sends directly to the invoice address shown in the UI, simulating an external payer scanning the QR code. Asserts against UI controls (AutomationIds) to verify what the user actually sees. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add CreateWalletWithoutPassword(network) to IWalletAppService — uses the "DEFAULT" encryption key convention already established by FrictionlessSensitiveDataProvider, to be replaced by secure storage later. InvestPageViewModel now calls EnsureWalletExistsAsync() before generating the receive address in both on-chain and Lightning paths. If no wallet exists, one is created silently so the user doesn't need to visit the Funds section before investing. Update integration test to remove explicit wallet creation — the invest flow handles it automatically. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New test: OneClickInvestLightningFundedTest exercises the complete Lightning invest flow end-to-end. Uses a ThunderHub GraphQL client to pay the BOLT11 invoice from LND-2 at thunderhub.thedude.cloud:4005. Flow: navigate to project → set amount → submit → pay invoice instead → switch to Lightning tab → wait for Boltz swap invoice → ThunderHub pays invoice → Boltz claims on-chain → payment detected → build investment → success screen. Also adds: - ThunderHubClient helper (GraphQL login + pay mutation) - InvestLightningTab AutomationId Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The InvoiceString TextBlock uses TextTrimming="CharacterEllipsis" which truncates the BOLT11 invoice. The test now verifies the UI shows an invoice (prefix check) but reads the full string from the VM's LightningInvoice property to pass to ThunderHub for payment. Also fixes the prefix check to match testnet invoices (lntbs prefix). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…se Thub-Auth cookie ThunderHub uses a hashed account ID (not the display number) and returns the JWT in a Set-Cookie: Thub-Auth header (not SSOAuth). The client now: - Queries getServerAccounts to resolve "LND-2" → hash ID - Extracts the Thub-Auth JWT from the login response Set-Cookie header - Sends it as a Cookie header on subsequent requests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Lightning test now reads THUNDERHUB_URL, THUNDERHUB_ACCOUNT, and THUNDERHUB_PASSWORD from env vars and skips if not set. No credentials in source. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…b auto-pay The test now logs the full BOLT11 invoice to the console so it can be paid manually via ThunderHub UI. The automated ThunderHub payment code is commented out with a TODO to re-enable when env vars are configured. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BoltzWebSocketClient only implements IAsyncDisposable, so the ServiceProvider cannot be disposed synchronously. Check for IAsyncDisposable first and call DisposeAsync(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dangershony
approved these changes
Apr 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
BuildInvestmentDraftto fail with insufficient funds. Now uses252 + (stageCount × 43)based on the deterministic investment tx structure (1 P2WPKH input, 1 P2WSH angor fee, 1 OP_RETURN, N P2TR stages, 1 P2WPKH change).StageCountis passed from the viewmodel which already knows it.CreateWalletWithoutPassword(network)toIWalletAppServiceusing the"DEFAULT"encryption key convention (same asFrictionlessSensitiveDataProvider). The invest flow now silently creates a wallet if none exists, so the user doesn't need to visit Funds first.InvestPageViewandInvestModalsViewfor headless integration testing (Appium-portable).OneClickInvestOnChainFundedTest— navigates to project, types amount, clicks "pay invoice instead", reads address from UI, faucet sends funds, waits for success modal. All assertions via AutomationIds.ContinueSpinnerandContinueTextnaming.Test plan
OneClickInvestOnChainFundedTestagainst docker testnet stack🤖 Generated with Claude Code