Repository navigation
chore: prepare Bitkit 3.1.1 - #1298
piotr-iohk wants to merge 10 commits into
Conversation
chore: adopt Paykit 0.1.1-rc6 (cherry picked from commit fe0cc2d)
feat: use the pubky.app profile directly (cherry picked from commit a1dbb83)
chore: bump ldk-node and vss client (cherry picked from commit 1ebdfc5)
chore: bump ldk-node to 0.7.0-rc.80 (cherry picked from commit 1b56274)
chore: bump paykit to 0.1.1-rc8 (cherry picked from commit a9c1a9b)
ci: pass Blocktank regtest auth to E2E jobs (cherry picked from commit 8adc704)
|
After 3.1.1 ships from this branch, close this PR without merging. A separate follow-up PR will bump the version and update the 3.1.1 changelog on Validation after the profile-tag fix. Results before the tag-preservation fixThe first migration run hit HTTP 401 in all four React Native wallet setup jobs. The setup jobs failed while funding the legacy app, before exercising the iOS 3.1.1 migration. iOS #1250 is now backported in
The integration dispatch uses signed commit The standard matrix exercises native 3.1.0 upgrade and restore and RN 1.1.6 upgrade and restore. It supersedes the extended migration run. Both RN fixture jobs funded wallets successfully with auth. The restore fixture’s first attempt showed a legacy-app broadcast timeout and passed on retry with the same app and suite. Both restore cases retried after Appium session creation timed out before the test started. The logs show both restores completed on attempt 2. The migration suite ran E2E commit The local run used E2E commit The native UI failure was in The iOS staging job funded and mined both deposits in the two-receipt case. Its first and third attempts timed out creating an Appium session. Attempt 2 showed the dev-mode-disabled toast in the recording, though the test missed it. The send amount was $1.11 when the test expected $1.01, and a late receipt overlay covered Send after the second deposit. Those two cases need a focused repeat to distinguish timing from an app issue. All three passed on the shipped 3.1.0 staging run. 3.1.0 staging control |
[Medium impact] The changes reach public profile editing and payment-request workflows in the iOS app. Preserve the restored profile's unread-tags flag before merging so profile creation cannot erase saved tags. Findings
SummaryPrepares Bitkit 3.1.1, build 204.
One fix is needed: profile creation must preserve the restored profile's unread-tags flag. Diagram%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Load own profile] --> B[Read Paykit copy and tags]
B --> C[Read pubky.app profile and revision]
C --> D[Show profile]
D --> E[Save changed fields at loaded revision]
E --> F{Revision still matches?}
F -- No --> G[Reload and ask user to edit again]
F -- Yes --> H[Save pubky.app profile]
H --> I[Update Paykit copy and tags]
Reviews (1) · Last reviewed commit: "Merge pull request #1250 from synonymdev..." · Reviewed by Greptile |
talosmachina
left a comment
There was a problem hiding this comment.
1 finding (1 P1). Prepares Bitkit 3.1.1 (build 204) on release-3.1.1 from v3.1.0: five backports, the version bump, the changelog, and a test commit that authenticates the staging regtest fixtures. Reviewed b03f4a6, full tier, static.
What I checked, and 3 candidates I ruled out
Backports: #1235, #1252, #1290, #1292 and #1250 carry the same changed lines as their merges on master. #1237 differs by 8 test-only lines (fixture ids and two new PrivatePaymentListDeliveryReport / proposal fields that exist only on master), consistent with the body's "adapts the Paykit and reauthentication tests to the release baseline".
Version commit c4bfb15: MARKETING_VERSION 3.1.1 and CURRENT_PROJECT_VERSION 204 on every target, three fragments consumed into CHANGELOG 3.1.1.
Test commit b03f4a6: BlocktankRegtestFixture reads BLOCKTANK_REGTEST_AUTH and posts to the staging fixture API; the secret is passed only on a workflow_dispatch of release-3.1.1 with no pr or merge_commit input.
Merge to master: git merge-tree against master conflicts in AddressTypeIntegrationTests.swift, PaykitSdkIdentityCheckTests.swift, UtxoSelectionTests.swift; integration-tests.yml auto-merges (finding below).
CI on the release branch: integration-tests, unit-tests and the E2E runs were still in progress when I read them.
Build: not built here; iOS does not build on Linux.
Cold reader: had not answered on the P1 when this was posted; the finding rests on the merge-tree output and the workflow's own dispatch inputs.
Ruled out
- Fixture credential reaching PR code on master: the
envcondition pinsgithub.ref_name == 'release-3.1.1'and emptypr/merge_commit, so onmasterit evaluates to''. - Fragments collected twice after the merge: master's copies of 1235/1237/1290 come back into
changelog.d/nextand are collected under[Unreleased]next release; same pattern as 3.0.1, a process choice. - Test-file conflicts:
masterreplaced the Blocktank fixture calls withLocalRegtest; resolving to master's side is correct.
Merge confidence: 3/5, one P1 in the workflow that the merge to master carries over.
Reviewer model: claude-opus-5-5
Reasoning effort: Not exposed (the run metadata names the model only)
|
@piotr-iohk this conflicts with |
|
@jvsena42 Thanks for flagging the conflicts. This PR is for reviewing 3.1.1, which is based on After 3.1.1 ships from this branch, we’ll close this PR without merging and open a separate PR on |
3.1.1 validation after the profile-tag fixThe release branch now includes the tag-preservation fix in signed commit
The RN restore fixture recovered from a keyboard permission prompt and a transaction broadcast timeout in RN 1.1.6. All candidate migration cases ran. |
There was a problem hiding this comment.
Verdict: eb94e76 were still running when I posted.
Findings: none.
QA for eb94e76:
Check: The picks match the 3.1.1 list ✅ The picks are #1237, #1235, #1252, #1290, #1292 and #1250, in that order. All match their master merges except #1237, which differs only in its tests.
- Checked with
git log --first-parent v3.1.0..eb94e76. Each pick's changed lines were diffed against its master merge. - #1237 differs by 8 test lines: a fixture id, plus
acknowledged,proposalRecordedAtandacceptanceRecordedAt, which exist only on master. - Four more commits are direct:
6bcce8f77(the 3.1.0 changelog line now links #1140; the same commit is on master), the version commitc4bfb1573, the staging-fixture test commitb03f4a610, and the tag fixeb94e76cd. - Nothing else is in the patch. No bitkit-core rc15 (#1295) and no Spark/Breez code: the added lines have 0 matches.
Check: Dependency pins ✅ bitkit-core stays at `0.8.0-rc11` (revision `22e0acc`). ldk-node is `0.7.0-rc.80`, vss-client `0.5.26-rc2` and Paykit `0.1.1-rc8`.
The project.pbxproj and Package.resolved changes against v3.1.0 touch only those three packages and the version numbers.
Check: Restoring a profile keeps its tags ✅ Without the fix, a restore save erases the stored tags. With it, they are kept, and no other save path loses them.
The bug at b03f4a610, without the fix:
CreateProfileViewkeeps the restored profile asexistingProfile, loaded throughPubkyAppProfileStore.load. That is the production resolver:AppScene.swift:460uses the default.- When the copy read fails, the profile has empty tags and
tagsUnread = true(PubkyAppProfileStore.swift:191). - A later
loadreads the copy and removes the key fromtagsUnavailable(:151). It also remembers the same revision with the real tags (:195). - On Save,
copyUnreadis false (:219), sostoredCopyskips the read (:335). The form's[]differs frompreviousTags, so the copy is published with no tags.
The fix: eb94e76cd passes existingProfile?.tagsUnread through createIdentity and createProfile into save (CreateProfileView.swift:237, PubkyProfileManager.swift:505/541/778). The store then re-reads the copy and merges the stored tags in (:345-348).
The other save paths: the edit screen (EditProfileView.swift:163) and the profile screen's tag add and remove (ProfileView.swift:284) pass the tagsUnread of the profile they show. The flag travels with the profile, so a load that clears the store flag cannot make a stale form look readable. The load's copy refresh (:196-204) runs only after a successful read. The migration writes to pubky.app only.
The commit: it matches #1303's code commit line for line. Only the changelog fragment is dropped, which is right: this bug never shipped. @jvsena42 reviewed #1303 on master with no findings.
Check: Version and release notes ✅ `MARKETING_VERSION` is 3.1.1 and `CURRENT_PROJECT_VERSION` is 204 on all six app targets. The three fragments are collected into `[3.1.1] - 2026-11-12`, and the compare links are updated.
These notes do not block the release:
Check: CI at eb94e76 ⏭️ Unit, native UI, integration and standard migration passed. Local E2E and staging E2E were still running.
- Unit and native UI
- Integration
- Migration
- Local E2E is still running.
- Staging E2E is still running. Multi-address and transfer have passed; nightly UI and Pubky are not finished.
The earlier candidate's comment left two staging cases to repeat: the $1.11 vs $1.01 amount, and the receipt overlay covering Send. They belong in that staging run.
Considerations:
- A removed tag can come back: if a load fails to read the copy while the edit form is open, it remembers the form's revision with empty tags (
PubkyAppProfileStore.swift:195,:322-330). A save that removes a tag then merges the stored tags back, so the removed tag returns. If the re-read also fails, a "tags not saved" error appears. No stored tags are lost. - Talos's
cache-mode: readpoint onintegration-tests.yml: this applies only if this branch merges into master. The PR closes unmerged, and the master follow-up carries only the version and the changelog. BLOCKTANK_REGTEST_AUTH: it reaches the integration job only on aworkflow_dispatchofrelease-3.1.1with emptyprandmerge_commitinputs. Apull_requestrun gets an empty value, so the fixture tests fail there by design.
No device cases were driven here, and I could not show that the new journeys J1–J3 ran at this head. Staging uses e2e main (0ca01e0a2), and its pubky job had not finished. The runs come from @piotr-iohk's validation after the tag fix. The review covered the full v3.1.0...eb94e76 patch, statically.
Twin: synonymdev/bitkit-android#1878 has the matching picks and the same restore fix. Its extras are explained: #1798 is Android-only, and there is no iOS-style test commit. Android has a HIGH that iOS does not have: it reads a global unread flag at save time, while iOS carries the flag on the profile.
Reviewed by claude-opus-5-5
|
Ovi’s review found no iOS code defects. The signed changelog update in The iOS edit and tag flows carry the unread status on the profile they display. If a Paykit read fails during an edit, the conservative merge can still keep a tag the user tried to remove. That behavior preserves stored tags during the outage and remains in this patch.
The changelog is the only diff between |
|
@ovitrif @jvsena42 Could you review the iOS 3.1.1 release candidate at |
There was a problem hiding this comment.
Verdict: ✅ Approve. I found no new defects. Release CI has finished successfully, and the latest commit changes only the changelog.
Findings: none.
QA for accbdd6:
Check: Release scope and dependencies ✅ The selected backports, dependency pins and release metadata match the intended 3.1.1 release.
I compared each backport with its original merge. The production changes match; the Paykit backport differs only in tests adapted to the release baseline. The restore-tag follow-up retains the form's unread-tags flag through publication.
The app and extensions use version 3.1.1, build 204. The pins are ldk-node 0.7.0-rc.80, VSS client 0.5.26-rc2, Paykit 0.1.1-rc8, and unchanged bitkit-core 0.8.0-rc11. The changelog now includes the VSS client and Paykit rustls updates.
Check: Edit the shared pubky.app profile ✅ J1 has a recorded device pass on the unchanged edit path.
The profile device report at 49f305a3f shows the name edit reaching pubky.app, preserving its other fields and tags, and surviving relaunch. The edit form, profile screen and profile store match the final source backport. Later changes preserve the unread-tags flag during profile restoration and do not change this journey.
Check: Refuse an oversized request note and send a shorter one ✅ J2 has a recorded device pass on the unchanged proposal and error-handling paths.
The Paykit device review at a1c126d records rejection of the 256-heart note with “Shorten the note and try again.”, followed by “Coffee” reaching the payer's 1,000-sat confirmation. The confirmation was closed without paying. The proposal service and error handling are unchanged in this release.
Check: Explain a rejected signup code ✅ J3 has a recorded device pass on the unchanged signup-error path.
The same Paykit device review records the specific rejected-code message, an available Authorize button, and no identity after canceling. The authorization sheet's handler matches that tested source.
Check: Completed release validation ✅ The release candidate's executable changes passed CI.
These runs tested eb94e76; git diff eb94e76..accbdd6 changes only CHANGELOG.md.
- Unit and native UI, including the restore-tag regression.
- Integration, including the authenticated funding fixtures.
- Local E2E, using the shipped 3.1.0 suite.
- Staging E2E, including the earlier amount-entry and two-receipt cases.
- Standard migration, covering native 3.1.0 and RN 1.1.6 upgrade and restore.
The logs confirm nightly UI and Pubky/Paykit passed after Appium startup retries. The standalone staging transfer and multi-address jobs ran no cases; multi-address coverage ran within nightly UI. The unit/native UI run also retains its reported skips.
Check: Build the reviewed head ✅ A fresh build of `accbdd6` succeeded.
Built from source with Xcode 27.0, Debug/E2E, arm64 for iOS Simulator. The resulting app reports 3.1.1 (204). SwiftFormat 0.64.0 lint on the changed Swift files, translation validation and git diff --check also passed.
I reviewed the full release patch, 6bcce8f...accbdd6, including production code, tests, workflows, pins and release notes. The three listed journeys rely on the linked device recordings and were not re-driven. The restore-tag race and other concurrency/error paths received code review and automated coverage, rather than a new device run.
Twin: bitkit-android#1878 chore: prepare Bitkit 3.1.1 matches the shared profile, proof-sizing, signup-error and USDT timing behavior, including the restore-tag follow-up.
Reviewed by gpt-6.1-sol-high
Release PR: reviewed and ready to release, but kept unapproved so it can't merge before the store release.
|
✅ Ready to release: review at accbdd6, no findings. I dismissed both approvals on this PR: a release PR stays unapproved until after the store release, so it can't be merged by accident. |
Twin: synonymdev/bitkit-android#1878
Prepares Bitkit 3.1.1 (build 204) from
v3.1.0, with the version bump and collected hotfix changelog.Description
Design
No separate release design; profile behavior and QA details are in the linked backports.
Preview
See the profile backport for the feature preview.
QA Notes
Setup
The runs below test
c4bfb15735cd9131150116113f77b60b4684d55bonrelease-3.1.1using the E2E repository’smainbranch. Migration uses the archived native 3.1.0 build and includes the extended RN 1.1.6 cases.Journeys
edit-pubky-app-profile.xml— profile changes are shared with pubky.app.request-note-too-long.xml— an oversized Paykit note is rejected before submission.grant-signup-rejected-code.xml— a rejected signup code gets a clear error.Automated Checks
Evidence
Local backend simulator app built and verified; 669 targeted tests passed on iPhone 17. SwiftFormat and translation validation passed.
Gaps
Full E2E and migration results are tracked in the linked runs. Device journeys are separate from the local unit tests.
Models used
GPT-6(reasoning:Not exposed)GPT-6(reasoning:Not exposed)The session exposes the model family but not its variant or reasoning setting.