v6.13.0 - #2678
Merged
Merged
Conversation
The disclaimer dialog resolved a datasource from the service locator inside a widget, so the ui layer talked straight to data (AGENTS.md rules #2/#6), and the receive feature reached into settings/ui/widgets for it (rule #1). The flag now travels the normal chain: a PayjoinDisclaimerRepository interface in domain, a SharedPreferences implementation in data, two usecases, and SettingsCubit holding the state. One boolean does not justify a datasource forwarding two calls to a repository forwarding them back, so it collapses into the repository. The dialog becomes passive and moves to core/widgets, which also drops the cross-feature import: both call sites show it, then record it — never the other way round.
The seven keys this branch adds (disclaimer title and settings row, advanced settings title, the receive Additional Information tile and its placeholder, the message-for-sender label, the send-confirm payjoin row) were en-only. Short labels, not disclosure prose: PAYJOIN_FEATURES_PLAN F9 keeps the two disclaimer explanations on the translator pipeline, and those are untouched here. "Payjoin" stays untranslated in every locale, as the reviewed corpus already does (transactionStatusPayjoinAborted). Machine-authored — worth a native pass whenever the locale is next reviewed.
Pin payjoin crate to 1.0.0-rc.5 via SatoshiPortal fork
refactor(payjoin): UX updates from clean-install testing
Recovery was tied to locator setup, so foreground and background composition paths could instantiate protocol execution, while obsolete Workmanager schedules remained registered. Resolve the repository lazily, start recovery explicitly from foreground app initialization, cancel persisted background schedules, and keep log pruning on foreground cold start.
Session, expiry, watcher, disable, and restart callbacks could race through whole-row SQLite updates. A stale callback could overwrite terminal state, while a local failure after network publication could trigger a competing fallback or strand polling. Serialize effects per session and UTXO selection globally, use conditional monotonic SQLite transitions, reconcile both Payjoin and original transactions, resume unfinished sessions, retain retrying watchers until persistence converges, and reject duplicate sender publication. Cover the races with repository and independent-connection SQLite tests.
Disabling Payjoin settled active receivers before storing the setting. A transient settlement failure therefore left Payjoin enabled and able to accept new requests despite the user's choice. Persist the disabled setting first, then settle every receiver best-effort. Unresolved sessions remain durable for foreground startup recovery, while the setting stays fail-closed and prevents new receiver creation.
The receive summary derived its sats or fiat suffix through a non-reactive bloc read, so changing the selected unit or exchange-rate-backed value could leave stale text on screen. Select the complete derived suffix from ReceiveBloc state so the summary rebuilds whenever any of its amount, unit, currency, or exchange-rate inputs change.
Integration cleanup could expire rows while their PDK polling timers were still active, and three unimplemented scenarios used empty test bodies that reported false success. Stop each recovered poll before marking its row expired, and mark restart and insufficient-funds scenarios as explicitly skipped with the fixture or harness each still requires.
fetchReceivers and fetchSenders still carried an onlyOngoing branch with no caller: the disable sweep and startup recovery deliberately read every row and decide from the freshest one under a session lock. A test stub also still referenced the dead parameter. Remove the parameter and its filtering branch, leaving filtered reads to fetchAll, and drop the stale stub.
The API legitimately sends order values the app refused to parse: status 'Expired' (distinct from 'Payment deadline expired'), payout status 'Failed', order type 'Sell USDT', empty payin/payout statuses, and null exchange rate and confirmation deadline fields on admin-initiated orders. Both batch parse layers turned the first such order into an empty list, hiding every exchange transaction in the app. - Parse per element with skip-and-log at both layers (datasource listOrderSummaries and repository getOrders), and in getOrderByTxId. - Make OrderStatus, OrderPayinStatus, OrderPayoutStatus and OrderType tolerant of unknown values; add the known missing members. - Render unknown order types generically via a new Order.generic variant carrying the server-sent type name. - Relax exchangeRateAmount, exchangeRateCurrency and confirmationDeadline to nullable, matching the server contract, with null guards at their consumers. - Read reward amounts from the payout side; the payin side is empty for admin-initiated orders and rendered every reward as 0 sats. - Derive fiat-vs-sats display from the order instead of a hardcoded variant list, fixing fiat refunds shown as sats and BTC balance adjustments formatted as fiat. Closes #2526 Closes #2527
…method
- Show the network on default wallets in the buy dropdown: Instant
payments (L-BTC on Liquid) / Secure Bitcoin (BTC on Bitcoin chain).
External and custom wallets keep their own names.
- Split the confirm page's Payout method row into Payout wallet and
Payout method, sharing the network phrases with the dropdown.
- Success message now includes what was paid: 'You bought {amount}
with {fiatAmount}' from the order's payin side.
- Below-minimum (and any other) order-creation failures are no longer
silent: the amount screen renders limit errors with the server's
amount and currency, and everything else through a neutral fallback
message. Previously only below-min/above-max variants rendered, and
most server errors never mapped to them, leaving Continue dead.
- Make the createOrder error parsing total via a shared Never-typed
helper across buy, sell, pay and withdraw: an error response can no
longer fall through to the result cast. Parses the server's singular
reason and new plural reasons shapes (API-Orders#859), tolerating
empty and limit-less entries.
- Stop converting fiat limit amounts with btcToSats: a 20 CAD minimum
rendered as 2,000,000,000 sats. Error entities now carry amount and
currency verbatim; the render site formats fiat as fiat.
- Repair broken translations the changed keys touched (zh/fa/th/tr
buyYouBought, zh payout-method and external-wallet strings).
Closes #2515
Closes #2516
Closes #2517
Closes #2518
…update
- 'Payment in Progress!' now says what is happening: 'The payment of
{fiatAmount} to {recipient} will be sent after your transaction
receives 1 confirmation onchain', with the recipient resolved from
the order (name, then label, then account identifier). Same
treatment on the completed screen, and the details table gains a
Recipient row.
- Once the payin confirms, the copy switches to 'Your transaction is
confirmed. The payment ... is being processed', driven by the
existing 5s poll.
- The success state now carries the post-broadcast order instead of
the stale pre-broadcast snapshot the bloc fetched and discarded.
- Transaction details: pull-to-refresh, and a proper error state with
Retry instead of skeletons that spin forever when the load fails.
- New localization keys instead of editing the old ones, so stale
translations fall back to English rather than silently dropping the
amount and recipient.
Closes #2524
Closes #2525
The Network fee priority row on the sell and pay confirmation screens was a debugPrint stub and every transaction paid the fastest rate. - SellBloc and PayBloc implement the shared fee modal's view-state and actions ports, following SendCubit's semantics: preset selection, custom sat/vB or absolute fees with arm/disarm/finalize, epoch-guarded previews, and a relay-floor gate on finalize. - The row opens the shared FeeOptionsModal and shows the committed selection; the summary fee reprices from a real PSBT built at the selected rate on every change. - Confirm prepares, signs and broadcasts at the committed selection. Unlike send and swap, the preview PSBT is display-only: sell and pay rebuild at broadcast time because a price-lock refresh can move the order's payin amount. The built fee is re-asserted against the relay floor before signing. - Fee editing locks while a confirmation is in flight or the payin is broadcast; handlers re-read live state so queued events are dropped, and every post-await emit merges into live state - a recalculation or preview landing after the flow moved on emits nothing instead of resurrecting a pre-broadcast state. - Previews price against the order's real payin address. Closes #2521
Build 212 uploaded and processed as VALID, but the workflow failed afterwards because its Developer API key cannot PATCH usesNonExemptEncryption. Apple documents ITSAppUsesNonExemptEncryption in Info.plist as the way to supply the same declaration with the app. Record false, matching the value read back from the last manually submitted valid build (204), and remove the action input so future uploads do not attempt a metadata PATCH that this deliberately least-privileged key cannot perform.
Build 212 proved the relevant release path end to end: both rustup binaries were wrapped, no rust-std target was downloaded during the Xcode archive, the signed IPA carried build number 212, artifact preservation succeeded, and Apple processed the upload as VALID. Remove the DEBUG/verbose diagnostics and their temporary make argument. Also remove the mutex: the root cause was cargokit reaching the second, unwrapped rustup and floating to stable 1.97.1. With both binaries pinned, all toolchains and targets are installed serially before Xcode and the successful run performed no Rust target install during the archive. Keeping a global rustup lock would unnecessarily serialize cargo builds and its timeout path could violate lock ownership. Keep the two-wrapper pin and its fail-fast assertions, and replace silent version/bundle tests with actionable annotations.
The App Store already contains builds 200 through 204, and the first successful CI upload created valid build 212 even though the subsequent metadata PATCH made the GitHub job red. Neither 200 nor 205 can now be reused for version 6.13.0. Set the shared pubspec build number to 213 and make it the only source of truth. Android already maps it to versionCode; iOS now maps it to CFBundleVersion after the Xcode override fix. Remove the workflow-run offset and the manual iOS-only override so the two stores cannot silently diverge again.
fix: resolve 61 security audit findings, mitigate 7, document 5 upstream
fix(ios): stabilize App Store Connect release uploads
# Conflicts: # ios/Runner/AppDelegate.swift # lib/features/send/domain/usecases/create_send_swap_usecase.dart # lib/features/send/presentation/bloc/send_cubit.dart # lib/features/transactions/application/usecases/get_transactions_usecase.dart # lib/features/transactions/transactions_locator.dart # localization/app_en.arb # localization/app_es.arb # localization/app_fr.arb # test/features/transactions/application/usecases/get_transactions_usecase_test.dart
feat: swap provider substitution
docs(release): document 6.13.0 changes
fix(startup): merge 6.12.x hotfixes into develop
Member
Author
|
@claude do you have any suggestion about that release keep in mind:
|
This comment was marked as resolved.
This comment was marked as resolved.
…ge-plan docs(payjoin): remove completed package plan
Member
Author
|
We removed PAYJOIN_PACKAGE_PLAN.md now that the package migration is complete. We confirmed that rollback remains hotfix-forward only, but we will keep that as an internal operational constraint rather than add it to the public changelog, since users cannot downgrade through the stores. |
…ack-broadcast feat(payjoin): add manual fallback broadcast
Member
Author
|
Test failing because Bob's mnemonic on testnet is empty |
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.
No description provided.