refactor(UI): more useful details on broadcast screen and more - #2010
Merged
Conversation
ethicnology
marked this pull request as draft
April 8, 2026 05:50
ethicnology
force-pushed
the
1247-more-useful-details-on-broadcast-screen
branch
from
April 8, 2026 05:53
e3450f8 to
8666604
Compare
Member
Author
|
rebased on develop |
ethicnology
force-pushed
the
1247-more-useful-details-on-broadcast-screen
branch
from
April 8, 2026 06:02
8666604 to
dbbbf88
Compare
Member
Author
|
rename & squash some commits |
ethicnology
force-pushed
the
1247-more-useful-details-on-broadcast-screen
branch
2 times, most recently
from
April 15, 2026 06:06
d23489c to
8eab6af
Compare
ethicnology
force-pushed
the
1247-more-useful-details-on-broadcast-screen
branch
from
May 18, 2026 05:59
1722e25 to
75ebeec
Compare
ethicnology
marked this pull request as ready for review
May 18, 2026 06:59
1 task
i5hi
reviewed
May 19, 2026
ethicnology
added a commit
that referenced
this pull request
May 19, 2026
Address follow-up review on PR #2010. Direction of dependency is now strictly electrum -> transactions, with all cross-module imports confined to the interface_adapters and DI layers. - Introduce ElectrumServersPort + adapter; fetch usecase no longer imports another usecase. - Move transaction_port from application/ to domain/ports/ to match the convention used by every other port in the codebase. - Relocate transaction_mapper from adapters/ to data/mappers/ to match the wallet module convention. - Drop cross-module domain dep: ElectrumTransactionRepository now returns the util BitcoinTx; mapping to the transactions domain entity happens in the port adapter. - Replace transactions/TransactionError thrown from the electrum usecase with electrum-local ElectrumFetchException subclasses; the port adapter catches and translates them at the module boundary.
ethicnology
force-pushed
the
1247-more-useful-details-on-broadcast-screen
branch
from
May 19, 2026 07:57
120bd76 to
cb000f2
Compare
ethicnology
added a commit
that referenced
this pull request
May 20, 2026
Address follow-up review on PR #2010. Direction of dependency is now strictly electrum -> transactions, with all cross-module imports confined to the interface_adapters and DI layers. - Introduce ElectrumServersPort + adapter; fetch usecase no longer imports another usecase. - Move transaction_port from application/ to domain/ports/ to match the convention used by every other port in the codebase. - Relocate transaction_mapper from adapters/ to data/mappers/ to match the wallet module convention. - Drop cross-module domain dep: ElectrumTransactionRepository now returns the util BitcoinTx; mapping to the transactions domain entity happens in the port adapter. - Replace transactions/TransactionError thrown from the electrum usecase with electrum-local ElectrumFetchException subclasses; the port adapter catches and translates them at the module boundary.
ethicnology
force-pushed
the
1247-more-useful-details-on-broadcast-screen
branch
from
May 20, 2026 09:40
9c502ce to
713ecd8
Compare
Member
Author
|
@i5hi done |
ethicnology
added a commit
that referenced
this pull request
May 21, 2026
Address follow-up review on PR #2010. Direction of dependency is now strictly electrum -> transactions, with all cross-module imports confined to the interface_adapters and DI layers. - Introduce ElectrumServersPort + adapter; fetch usecase no longer imports another usecase. - Move transaction_port from application/ to domain/ports/ to match the convention used by every other port in the codebase. - Relocate transaction_mapper from adapters/ to data/mappers/ to match the wallet module convention. - Drop cross-module domain dep: ElectrumTransactionRepository now returns the util BitcoinTx; mapping to the transactions domain entity happens in the port adapter. - Replace transactions/TransactionError thrown from the electrum usecase with electrum-local ElectrumFetchException subclasses; the port adapter catches and translates them at the module boundary.
ethicnology
force-pushed
the
1247-more-useful-details-on-broadcast-screen
branch
from
May 21, 2026 10:16
025963a to
a3bb57d
Compare
Broadcast screen - Resolve PSBT inputs via ElectrumTransactionPortAdapter (new lib/core/transactions/ module: entities, ports, cubit, mapper, build/fetch usecases, transaction_screen). - Robust mapper: catch-all scriptPubKey decode, testnet flag passing. - Liquid txid mempool URL falls back to tx/<txid> when no unblindedUrl. Address / Transaction / Invoice viewers - New widgets in lib/core/widgets/: AddressViewer, TransactionViewer, InvoiceViewer (replace transaction_details_widget + transaction_label_bottomsheet). - Tap to open detail dialog, press to copy. Dotted underline for tappability, alternating group styles. - Detail dialog: segmented Address / Payment URI toggle for bip21. Receive screen - Refactor: split receive_enter_note into receive_enter_amount; receive_qr_screen redesign. - Payjoin: single switch row replaces "address only" + "payjoin activated" UI. URI no longer leaks across wallets or appears on empty wallets (hasUtxos / canPayjoin gates). - New label_entry_bottom_sheet + labels_facade. Misc - BlurredDialog unifies dialog widgets. - bordered_tappable_tile. - Remove unused price_input.dart.
Introduce ElectrumTransactionRepository so the fetch usecase depends on a port instead of SqliteDatabase, and register ElectrumRemoteDatasource as a singleton instead of building it per call. Move BitcoinTx -> domain Transaction mapping into the repository impl and BuildTransactionUsecase so presentation no longer imports adapters.
Address follow-up review on PR #2010. Direction of dependency is now strictly electrum -> transactions, with all cross-module imports confined to the interface_adapters and DI layers. - Introduce ElectrumServersPort + adapter; fetch usecase no longer imports another usecase. - Move transaction_port from application/ to domain/ports/ to match the convention used by every other port in the codebase. - Relocate transaction_mapper from adapters/ to data/mappers/ to match the wallet module convention. - Drop cross-module domain dep: ElectrumTransactionRepository now returns the util BitcoinTx; mapping to the transactions domain entity happens in the port adapter. - Replace transactions/TransactionError thrown from the electrum usecase with electrum-local ElectrumFetchException subclasses; the port adapter catches and translates them at the module boundary.
The prior commit (e2f56de) edited transaction_mapper and transaction_port at their new paths but never recorded the rename; git still tracked them at the old paths.
FetchElectrumTransactionUsecase had exactly one caller — ElectrumTransactionPortAdapter — and contained pure infrastructure orchestration (server priority + fallback + typed errors), not any business workflow. A use case called only by a driven adapter inverts the layer rule (ARCHITECTURE.md, AGENTS.md rule 2). Inline the fallback loop into the adapter, depending directly on ElectrumServersPort + ElectrumTransactionRepository + EnvironmentPort. The adapter now throws TransactionError directly; the intermediate ElectrumFetchException family had only one producer + one consumer, both inside the deleted use case path, so it follows the use case out. The integration test switches from the use case to TransactionPort — the equivalent public entry point — and still exercises the sqlite-cache flow through the same code path.
Address / transaction / invoice detail dialogs duplicated a `GestureDetector(Row(Icon+Gap+Text))` action row across three files. The bare row gave a ~14dp tap target — well below the 48dp Material recommendation — and the duplication invited drift between the three viewers. Extract a shared `ViewerActionButton` in lib/core/widgets/: InkWell-based, 44dp minHeight, full-width tap area, theme tokens only. Swap the three viewers over. While here, pass `mode: LaunchMode.externalApplication` to launchUrl in AddressViewer + TransactionViewer to match how the rest of the codebase opens external links and avoid `platformDefault` misfires on some Android setups.
When `data` is a BIP21 URI (e.g. send flow's `paymentRequestAddress` returning the raw URI on MRH paths, or copied/scanned raw payment requests), Satoshifier returns a `Bip21` value — not `BitcoinAddress` / `LiquidAddress`. The old if-chain only matched the bare-address types and fell through to `return null`, so Copy Link / Open in Explorer silently did nothing. Switch to a sealed-pattern match and add a Bip21 arm that routes by `network.isLiquid` and uses `parsed.address` — the embedded bare address — for the mempool URL.
…pters to adapters ElectrumServersAdapter (electrum), ElectrumServerAdapter (blockchain, wallet) previously depended on GetElectrumServersToUseUsecase — an application-layer use case invoked from secondary adapters, reversing the layer-direction rule. The usecase served these adapters only. Absorb the orchestration (fetch + filter custom + sort by priority) into ElectrumServerRepository.fetchActiveServers as a query method. The two non-electrum adapters compose it with ElectrumSettingsRepository and SettingsRepository (for tor proxy) inline. Delete the usecase plus its request/response DTOs. Relocate all touched files from the legacy interface_adapters/ folder to the canonical adapters/ folder (electrum, wallet — matching the blockchain move already in flight). Remaining interface_adapters/ usage in tor/mempool/swaps/status is out of scope for this PR.
lib/core/transactions/ was structured as a full feature inside core (domain + application + presentation + ui), violating the rule that core is infrastructure only. The cubit, screen, usecase, and ReviewableTransaction aggregate were consumed solely by lib/features/broadcast_signed_tx/. Split: keep the shared primitives in core (Transaction entities, TransactionPort, TransactionMapper) since electrum implements the port and depends on the mapper; move review-specific concerns into the broadcast_signed_tx feature. Errors split per-layer: TransactionPortError in core (thrown by the port adapter), TransactionReviewError in the feature (thrown by the usecase, wrapping port errors at the boundary). The view renders TransactionReviewError and unwraps the inner port error for granular messaging — never sees a foreign error type. Drop dead code: BuildTransactionUsecase had three execute methods — executeFromTransaction was internal-only and executeFromWalletTransaction was never called. Collapse to a single execute(). Drop unused TransactionMapper.fromLiquidTx and the dead TransactionParseFailed variant. Rename per AGENTS.md naming: TransactionEntity -> ReviewableTransaction (no Entity suffix), TransactionCubit -> TransactionReviewCubit, TransactionScreen -> TransactionReviewView (it's an embedded widget, not a routed screen). Folder layout per rule 14 — no single-file subfolders.
ethicnology
force-pushed
the
1247-more-useful-details-on-broadcast-screen
branch
from
May 22, 2026 07:40
a3bb57d to
8c200c3
Compare
…irectly EnvironmentAdapter still depended on GetSettingsUsecase — the same adapter→usecase inversion the earlier "drop usecase from adapter deps" commit claims to remove. Swap for a direct SettingsRepository dep so the cleanup is consistent.
LabelsFacade.fetchDistinctLabels() returned every label regardless of
LabelType. The receive note bottom sheet surfaces these as suggestion
chips, and the chosen string becomes BIP21 message= — counterparty
visible. A user could autocomplete a private transaction label
("Boss salary") into a sender-visible field.
Add an optional LabelType filter to the facade and pass LabelType.address
from the receive bloc. Send/tx call sites stay unscoped (private context).
…error leak, guard re-broadcast Three review fixes against the broadcast/review code I shipped: - BuildReviewableTransactionUsecase took btc_utils.BitcoinTx and called TransactionMapper directly. That's application-importing-adapter and foreign-type-in-usecase-signature in one — the same rule-2 violation the previous commit claims to fix. Cubit now does the mapping at the primary-adapter boundary; usecase takes a domain Transaction. - TransactionReviewError.portFailure(TransactionPortError) was ceremonial — the view destructured it and pattern-matched on the inner port-layer variants, leaking the foreign error type. Replaced with discrete feature-layer variants (fetchFailed, noServersAvailable, inputResolutionFailed, unexpected). Usecase translates port errors at the boundary. - broadcastTransaction's early-return checked isBroadcasting and transaction != null but not isBroadcasted. After a successful broadcast the button re-enabled and the same tx could be broadcast again. Added the missing guard.
i5hi
approved these changes
May 25, 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.
Closes #1247 #1832
For externally-signed PSBTs we can't assume which output is change and input amounts aren't available locally. Fees only compute by fetching parent transactions from Electrum.
Transaction review on broadcast screen
Shared port + feature split. Primitives (
Transactionabstract + concrete entities,TransactionPort,TransactionMapper) live inlib/core/transactions/since electrum implements the port. Review-side code (BuildReviewableTransactionUsecase,ReviewableTransactionaggregate,TransactionReviewCubit,TransactionReviewView) lives inlib/features/broadcast_signed_tx/. Inputs resolved viaElectrumTransactionPortAdapter→ fees + amounts shown for any signed PSBT regardless of origin.TransactionMappercatches all scriptPubKey decode errorsisTestnetpropagated so testnet outputs decodeMempoolUrlBuilderliquid txid falls back totx/<txid>when nounblindedUrlTransactionPortError(port) translated to discreteTransactionReviewErrorvariants at the usecase boundary — view never sees the foreign typeisBroadcasting/isBroadcastedguards prevent double-tap and re-broadcast after successAddress / Transaction / Invoice viewers
Unifies 15+ inconsistent display patterns (manual
truncateMiddle+ copy icon,CopyInput, custom substring).BlurredDialogwith full value in 4-char groups + copy + "View in explorer"clipboardTextparam copies a different value than displayed (e.g. full BIP21 URI when cell shows the address)clipboardTextis bip21BlurredDialog
Shared wrapper matching
BlurredBottomSheet.showAPI. AllshowDialogcall-sites migrated for consistent styling.Receive screen
receive_enter_notesplit intoreceive_enter_amount;receive_qr_screenredesignhasUtxos/canPayjoingetters gatepj=label_entry_bottom_sheet+labels_facade.fetchDistinctLabels({type})LabelType.addressso private transaction labels never autocomplete into a counterparty-visible BIP21message=Architectural cleanup
GetElectrumServersToUseUsecase— was being called from three secondary adapters (illegal layer direction). Orchestration absorbed intoElectrumServerRepository.fetchActiveServers; the affected adapters now depend on repositories directly. Request/response DTOs for the dead usecase deleted.EnvironmentAdapterswapped ontoSettingsRepositorydirectly (was the same adapter→usecase inversion).lib/core/transactions/was originally added as a full feature inside core — split per the architecture rules (primitives stay, feature concerns moved tobroadcast_signed_tx).interface_adapters/→adapters/for the touched modules (electrum, wallet, blockchain). Other modules' legacy folders untouched.TransactionMapper.fromLiquidTx,TransactionError.parseFailed.TransactionEntity→ReviewableTransaction(no Entity suffix),TransactionCubit/State/Screen→TransactionReview*, single-file folders flattened.Misc
TransactionDetailsWidget,BitcoinTransactionRepository,FetchBitcoinTransactionUsecase,TransactionLabelBottomsheet, unusedprice_inputbordered_tappable_tile(used by payjoin switch row)Known follow-ups (out of scope for this PR)
ElectrumTransactionPortAdaptershould narrow per-server error swallowing and stop leaking rawlastError.toString()into user-visible messagesblockchain/adapters/electrum_server_adapter.dartandwallet/adapters/electrum_server_adapter.dartare byte-identical and could share an impl via a unified port (pre-existing duplication)interface_adapters/→adapters/migration still pending intor/,mempool/,swaps/,status/,recipients/,electrum_settings/,recoverbull/,withdraw/,pay/,onboarding/`