Skip to content

iOS 4.2.1 (2026.11.11): PIN lifecycle fix and wallet release - #1315

Closed
takemiyamakoto wants to merge 57 commits into
masterfrom
hotfix/4.2.0-polkaswap-usability
Closed

takemiyamakoto wants to merge 57 commits into
masterfrom
hotfix/4.2.0-polkaswap-usability

Conversation

@takemiyamakoto

@takemiyamakoto takemiyamakoto commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Fearless 4.2.1 (2026.11.11) fixes a PIN setup race that could send a user back to the main screen after they left the PIN screen. UIKit can defer its disappearance callback until after a pending save finishes. The controller now cancels that completion when UIKit begins removing it from its parent. The release also includes the Polkaswap fixes, PIN keypad sizing, app-owned WalletConnect client, service-key fixes and optimized Solana retry fix from the preceding builds.

The regression test reproduced the race in 18 of 20 attempts on iOS 18.1. The fixed build passed 20 of 20 attempts on each of iOS 18.1 and 27.0, including animated and nonanimated navigation. The TON WebKit test now uses a visible scene and tracks the intended navigation.

Local validation for release source 098dc861e48ebdec6e5595688170cb554f8b5f15 is complete.

  • Full Debug suites on iOS 18.1 and 27.0 each passed 3,773 tests with 96 skipped. Source-equivalent Debug products were built at 4fc2b3a1a.
  • The optimized Release suite passed 3,701 tests with 95 skipped. The Core Data release suite passed all 478 tests. All four non-testable Release rehearsals passed first launch, relaunch and store preservation on iOS 17.5, 18.1, 26.5 and 27.0.
  • All 60 source checks passed after rerunning one with the pinned Fastlane version. The signed device binary retains the Solana signature before destroying its snapshot. Its full scan found the same 48 candidate sites as its predecessor.
  • The production archive passed its signing and storage-model audits. The audited export has SHA-256 a9ba1cba78615e55b131d2921aaf942766774d9fe4124236eb1f1f5a9eacab43. The device crypto host previously passed 11 of 11 sr25519 tests in optimized Debug with matching crypto inputs.

Apple accepted 2026.11.11 for normal App Review on 10 November at 10:32:58 UTC. The verified release policy is automatic release on approval. The build is also available on internal TestFlight. The previous build was rejected. The reviewer’s specific reason was unavailable when the owner directed resubmission. The in-place iPhone update was verified and the cold-launch observation was pending at submission.

Release record and artifact hashes

takemiyamakoto and others added 3 commits November 7, 2026 10:48
Two Polkaswap screens broke on iPhone with the 4.2.0 redesign (#1305):

- The token picker stretched its search field over most of the sheet
  and left the list a strip at the bottom. SearchTextField took its size
  from BackgroundedContentControl's empty contentView, a zero height,
  and #1305 replaced its fixed height with a 44 pt minimum, so the
  sheet's stack view stretched the field. The field now reports its own
  height and hugs it, and the list and its empty state share a container
  so the hidden empty view no longer fights the list's height.
- Preview pushed the confirmation inside the new swap tab, where the tab
  bar and the raised Polkaswap button covered Confirm and the header sat
  under the status bar. The confirmation now hides the tab bar and keeps
  its header and button inside the safe area.

Both tests fail on the previous code: the search field measured 653 pt
in an iPhone-sized sheet, and a tap on Confirm reached a tab button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On 4.2.0 a swap quote could take minutes to appear. Since #1305 every
quote request carried its own ID and only the newest request's reply was
shown, while every SORA block (about 6 s) cancelled the pending request,
hid the shown quote and asked again. Any reply slower than a block was
therefore thrown away, block after block, until one happened to be fast
enough. Quotes also queued in the app-wide operation queue behind
unrelated work, waited 0.8 s after each keystroke, and replaced block
subscriptions kept refreshing because the subscription service cancels
them as requests, which leaves them running on the node.

- A reply is shown when it answers the question on screen (pair, amount,
  direction, market) and nothing newer is shown, so a refresh no longer
  invalidates the reply already on its way. Replies to an old amount and
  older replies are still dropped.
- A block refresh keeps the shown quote, sends nothing while a reply is
  awaited, and a failed refresh keeps the quote instead of clearing the
  inputs behind an alert.
- Quotes go straight to the SORA socket with a 10 s timeout; fees and pair
  checks use the swap screen's own operation queue.
- Typing waits 0.3 s instead of 0.8 s.
- Updates from replaced block subscriptions are ignored.

In the simulator, against the production SORA nodes, the time from
keystroke to quote fell from about 1.8 s to 0.7 s. The new presenter test
fails on the previous code: the awaited reply is discarded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026.11.5 went to TestFlight and App Review on 4 November 2026, so it
joins the consumed builds and becomes a supported in-place upgrade
predecessor in the usability gate. The startup capture keeps accepting it
under its own name, every release tool now pins 2026.11.6, and the
build-number check's test treats 2026.11.5 as the latest consumed build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemiyamakoto
takemiyamakoto requested review from a team as code owners November 7, 2026 01:55
takemiyamakoto and others added 2 commits November 7, 2026 11:01
Apple approved 4.2.0 with build 2026.11.5 (Pending Developer Release on
7 November 2026), which closes 4.2.0 to new uploads, so the Polkaswap
fixes ship as 4.2.1 (2026.11.6). The Release target, the archive,
identity, signed-artifact and build-number checks, the usability gate and
fastlane now expect 4.2.1. The startup capture still expects 4.2.0 for
every earlier build and 4.2.1 only for 2026.11.6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The self-test parsed the check's output with a literal "Release 4.2.0"
and used 4.2.0 in its version-drift cases, so it stopped recognising a
passing repository once the release moved to 4.2.1. It now reads the
version and build from the check's output and uses them in every case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemiyamakoto takemiyamakoto changed the title iOS 4.2.0 (2026.11.6): make Polkaswap swaps usable again iOS 4.2.1 (2026.11.6): make Polkaswap swaps usable again Nov 7, 2026
takemiyamakoto and others added 2 commits November 7, 2026 12:01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the owner's word, 4.2.0 (2026.11.5) was removed from review, its version
record renumbered to 4.2.1 with build 2026.11.6, and submitted on
7 November 2026 at 10:06 UTC. It is Waiting for Review with a manual release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
takemiyamakoto and others added 4 commits November 7, 2026 22:40
verify-native-source.py accepted SOURCE_PACKAGES_DIR from its callers but never
read it, so a moved tag or an edited package checkout passed the check. It now
compares every pinned checkout's HEAD with its revision and refuses local
changes, using git --no-optional-locks so the check never writes.

verify-pods.py and config/pods-source-pins.json record digests of the 11 pods
compiled into the app or its tests and of the rswift and swiftformat
executables that Xcode runs. The rswift digest equals the upstream 6.1.0
release binary. Recorded from the reviewed 4.2.1 install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
createPublicKeySoft copied SR25519_KEYPAIR_SIZE (96) bytes out of a 32-byte
stack buffer, reading stack memory into the key and always failing. Nothing
calls it today; it now copies the 32-byte public key and a test checks it
against the soft-derived key pair.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tonkeeper/ton-api-swift 0.1.7 has no licence file. Packages/TonAPI holds the
same client generated here by Apple's swift-openapi-generator 0.3.1
(Apache-2.0) from the MIT-licensed opentonapi specification, with provenance
in its README. Client.swift is byte-identical to ton-api-swift's; Types.swift
is byte-identical after postprocess.py drops Action._type, as ton-api-swift
did, so a new tonapi action kind cannot fail a history page.

scripts/deps/regenerate-tonapi.sh rebuilds the pinned generator and fails if
the committed sources differ from fresh output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner, 2026-11-07: fix the key-exposure audit findings, and "don't use any
closed source libraries. make everything you need here in this repo, open
source".

Closed and non-open-source code:
- Delete the closed Kotlin/Native sorawallet framework, loaded at every
  launch. Its only use, Polkaswap strategic-bonus APY, is now Swift
  (PolkaswapAPYWorker, PolkaswapPoolApyMapper) against pi.soramitsu.io; the
  framework's SubQuery endpoint answers 503.
- Remove WalletConnect (reown-swift, WalletConnect Community License) with its
  prebuilt yttrium binary and five Reown-only packages. A one-time clean-up
  deletes only com.walletconnect.sdk generic passwords and WalletConnect
  defaults. Keep the Chainlink ABI code under its web3swift and MEWwalletKit
  licences.
- Build against the in-repo TonAPI package instead of ton-api-swift.

Key exposure:
- The emergency recovery export becomes a password-encrypted file (scrypt plus
  XSalsa20-Poly1305, 8+ characters, verified before sharing) and never shows a
  secret; scripts/recovery/decrypt-emergency-material.py opens it.
- Forget wallet (now PIN-gated) and logout erase the Keychain secrets of
  removed wallets that were backed up, after their rows are gone. Orphaned keys
  and never-backed-up wallets' keys stay recoverable through the encrypted
  export.
- PIN lockout with backoff persisted in the Keychain, constant-time compare,
  biometric enrollment checks that trust an existing install's first unlock,
  a 5-minute monotonic background re-lock, and PIN or biometrics before every
  fund-moving or staking submission.
- JSON exports need 8+ characters; secret files get complete protection, their
  own directories and removal after sharing; Inbox copies and old leftovers are
  removed.
- Remote SVGs are filtered before SVGKit; seed and key share sheets exclude
  Copy; secrets hide while the screen is captured and screenshots warn;
  keyboard extensions are refused.
- TON Connect never signs a ton_proof for a site its manifest does not come
  from, and gets a veto-only kill switch.
- Xcode now runs the checkout and pod verification before any build tool.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
takemiyamakoto and others added 12 commits November 7, 2026 23:53
2026.11.6 is in App Review and counts as consumed; 2026.11.7 replaces it in
review with the closed-source removal and the key-exposure fixes. Release
tools, gates and their tests now pin 4.2.1 (2026.11.7), as cc8e3ec and
1092c5e did for 2026.11.6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…26.11.7)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Packages/FearlessWalletConnect speaks WalletConnect v2 in the wallet role on
Apple's system frameworks only (Foundation, CryptoKit, Security, Combine). It
replaces Reown's reown-swift, which is under the WalletConnect Community
License and is not open source.

- X25519 key agreement, HKDF-SHA256 session keys, SHA-256 topics, and
  ChaCha20-Poly1305 type 0 envelopes in padded base64 (type 1 is read, never
  opened).
- The relay's EdDSA did:key sign-in JWT, valid for 24 hours.
- The relay over URLSessionWebSocketTask: subscribe, batch subscribe,
  publish, unsubscribe, the batch message fetch, acknowledging each delivery,
  keep-alive pings and reconnecting with back-off.
- Pairing, proposals, approval and refusal, settlement, requests checked
  against the session's namespaces, answers, ping, disconnection and expiry,
  with each Sign method's relay tag and lifetime.
- Verify: ES256 attestations from the relay, or the trusted service's answer
  by message hash.
- A strict JSON reader that keeps numbers exact and refuses duplicate keys.
- Its record in the app group's user defaults and its keys in one keychain
  item, and the import of what WalletConnectSwiftV2 (Fearless up to 4.1.0) and
  Reown 1.8.0 (4.2.x) saved, left in place for a downgrade.

Tests run on macOS with swift test: RFC 7748 and WalletConnect relay-auth
vectors, the wallet role against an in-memory relay that follows the live
relay's delivery rules, and both earlier storage layouts. Two checks use the
WalletConnect SDK installed outside the repository, never as a dependency:
scripts/walletconnect/reference-vectors.mjs for a differential cryptography
check, and reference-dapp.mjs as a dApp on the live relay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner, 2026-11-08, asked "Bring WalletConnect back on the new 4.2.1 head
with this client?": "Bring it back".

e0dda28 removed WalletConnect because reown-swift is not open source.
This restores the WalletConnect part of that commit on
Packages/FearlessWalletConnect and keeps everything else in it: the
key-exposure fixes, the removal of sorawallet and ton-api-swift, and the
source and pod verification phase.

- The WalletConnect service, screens, coordinators, models and tests come
  back as they were in 4.2.1 (2026.11.6), on FearlessWalletConnect instead
  of WalletConnectSign. Reown's socket engine, socket factory and crypto
  provider stay deleted.
- Forgetting a wallet and logging out disconnect its WalletConnect sessions
  again, after the new secret erasure.
- RetiredWalletConnectDataCleanup is removed. It deleted the
  com.walletconnect.sdk Keychain items and WalletConnect defaults that the
  client imports, so sessions paired in 3.0.5 to 4.2.1 (2026.11.6) carry
  over again. Devices that already ran 2026.11.7 lost them; their dApps
  pair again.
- RLPBigInt.swift and SignTypedData.swift (MEWwalletKit, MIT) return to
  WalletConnect/eip_mew with that licence and a NOTICE entry; the regex
  helper the ABI move dropped is String+Match.swift there.
- The release audits again require WalletConnect.projectId
  (FL_WALLET_CONNECT_PROJECT_ID) and check that the WalletConnect service
  uses the entitled app group.
- No package is added: the resolved graph stays at 40 external packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/walletconnect-protocol.md describes Packages/FearlessWalletConnect:
its files, the wire format, its storage, the import of what earlier SDKs
saved, and how to rerun its checks, including the real-storage upgrade
check from a Reown 1.8.0 build. It notes that 4.2.1 build 2026.11.7
deleted those records once per install, so a device that ran that build
has nothing to carry over and its dApps pair again.

The binary provenance record says the wallet now speaks WalletConnect
with its own client on Apple's system frameworks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WalletConnect pairing codes use the `wc:` scheme (EIP-1328), but the QR
matcher accepted `ws:` instead, so a scanned pairing code was reported as an
invalid QR code. `WalletQRService` now matches `wc:` codes itself, from the
camera and from gallery images, and no longer reports a `ws:` node address
as a pairing code (the shared decoder still does; its result is refused).

A new connection is only useful for signing, so `connect(uri:)` opens it
together with signing: while `WalletConnectSigningPolicy` is off, a scanned
code shows a localized "not available in this version" message and nothing
is paired.

This change also adds, in every bundled localization, the strings the
reworked WalletConnect request flow uses in the following changes.

Tests cover pairing codes and node addresses from the camera, the gallery and
the scanner, connecting with signing off and on, malformed codes, and the new
message in every shipped localization. The scanner tests now use `wc:` codes.

Ported onto the in-repo client (Packages/FearlessWalletConnect): the service
pairs through the client, or through an injected pairer in tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 805b624e2cadaa59856d89ea719e56ba9230e7b6)
…ation

Every request is now prepared before its confirmation opens, and the
confirmation and the signer use the same prepared values:

- The request must name an account the session approved for the request's
  chain. The signing key is that account's, not a match picked by address
  from all wallets.
- EVM transactions get their nonce, gas limit and gas price before the
  confirmation opens. The confirmation shows the network first, then the
  recipient (the token recipient or spender for ERC-20 transfers and
  approvals), the amount and the most the network can charge, and exactly
  those values are signed; nothing is quoted again after Confirm. Chain ids
  are parsed as the decimal values the app stores, a transaction for another
  chain is declined, and so is a request without a recipient.
- EIP-712 typed data must carry the request's chain id when its domain names
  one, and permits show their spender and amount. The legacy array format,
  which no domain binds to a network, is declined.
- Substrate transactions must carry the chain's genesis hash, spec version
  and transaction version. The call is decoded and must encode back to
  exactly the dApp's bytes; transfers show their recipient and amount, the
  fee is quoted for that exact extrinsic, and the tip is signed as sent.
- Substrate messages are signed inside the `<Bytes>…</Bytes>` envelope that
  polkadot-js uses.
- Personal-sign and typed-data signatures use the 27/28 recovery id that
  JSON-RPC callers and `ecrecover` expect.

Declined requests show a localized reason and get an error response, and the
request sheet no longer prepares the request again on every balance update.
`WalletConnectSigningPolicy.production` stays off.

Tests cover account binding, the quoted and exactly signed transaction for a
decimal chain id, chain-id, address and quantity checks, ERC-20 decoding, the
EIP-712 specification's example digest, permits, the `<Bytes>` envelope and
its signature, Substrate genesis, runtime and call checks against the bundled
Polkadot runtime, the signed payload, a runtime change before signing, and
the confirmation rows for every method.

Ported onto the in-repo client: the new files import FearlessWalletConnect,
and the project changes were applied to this line's project file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 59c74e0bf33f93f29593006dc1219cb4b39e2b08)
…sts behind the lock

- Signing now waits for the PIN or biometrics, asked from the confirmation
  after the user taps Sign. Closing the PIN screen signs nothing and leaves
  the request open to sign or reject; without a PIN nothing is signed, and a
  PIN screen that goes away without an answer counts as not confirmed.
- The PIN screen that locks the app after inactivity now records that the
  app is locked. While it is shown, WalletConnect requests and notices wait
  in their queue, and a request already on screen is hidden until the app is
  unlocked.
- A request the SDK delivers again while it is queued or on screen is shown
  only once.

Tests cover signing with and without the user's confirmation, the PIN screen
from the confirmation with its success and cancel paths, the missing-PIN
case, requests waiting behind the lock and appearing after it, one request
at a time, a repeated request shown once, the request window hidden while
locked, and the lock ending with its PIN screen.

Applied unchanged on the 4.2.1 line: the lock marker sits after the head's
unlock-PIN guard in FearlessApplication.dropSession().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit cc3e7ee3a6275c65e84f58f077de2781bcd66ebe)
…s scams

The SDK reports what WalletConnect Verify knows about the app behind each
proposal and request, but the service dropped it. It now reaches the
screens:

- The proposal shows a Verification row below the app: verified domain,
  domain not verified, or domain mismatch.
- The request sheet shows the same status under the app's name; a domain
  mismatch replaces the generic warning with one saying the app may not be
  the website it claims to be. The confirmation lists it as its last row.
- A proposal or request from an app Verify flags as a known scam is declined
  before anything opens, and the user is told which app was blocked and that
  nothing was connected or signed. This applies while signing is off too.

The notice presenter now serves both the signing-unavailable and the
blocked-app notices. The domain-mismatch status is shortened for the rows,
with its explanation as a separate warning, in every bundled localization.

Tests cover how every Verify result maps to what is shown, declined and never
shown scam proposals, scam requests declined before any confirmation with
signing on and off, verified requests opening with their status, the
blocked-app notice, the confirmation row, and the texts in every shipped
localization.

Ported onto the in-repo client: the client's sessionProposal and
sessionRequest events carry the VerifyContext its Verify client produced, and
a scam-flagged proposal is refused through the client (or an injected
rejecter in tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 1b9a737d14a75b715d8f3d722c7a682b8dd9dc18)
…submission PIN

Owner's decision for 4.2.1 (2026.11.8), relayed from the key-exposure
session: "we need some wallet connect support of course", choosing
"Connect and sign": pair from wc: codes and links, sign EVM, Polkadot and
TON requests, ask for the PIN or Face ID before each signature, show the
real requesting site, and let a remote kill switch turn signing off.

- WalletConnectSigningPolicy.production is on. The ported WC-SIGN checks
  stay in front of every key: the account the session approved, the
  network, the decoded call that must encode back to the dApp's bytes, the
  quoted fee, the <Bytes> envelope, and scam-flagged apps declined.
- Every signature asks through SubmissionAuthorizer, the step every
  fund-moving and staking submission takes, with its PIN lockout and
  biometric rules. Without a PIN nothing is signed.
- Remote vetoes, absent means enabled and only an explicit false pauses:
  evm_dapp_signing_enabled and polkadot_dapp_signing_enabled for
  WalletConnect, ton_dapp_signing_enabled for TON Connect transactions and
  ton_proof sign-ins, the Android key names; never dapp_enabled. A paused
  request is declined before anything opens and the user is told nothing
  was signed. The confirmation checks again before and after the PIN.
- The requesting site is shown as WalletConnect Verify reports it: on a
  domain mismatch the website row names the site the request came from,
  and a site Verify could not check is labelled "Domain not verified"
  with a warning.
- wc: links and fearless://wc?uri= links pair (Info.plist registers wc).
  A link that opens the app waits until WalletConnect starts after the
  unlock; a failed link gets a notice. A wc: link without a key only
  brings the wallet forward.
- New strings in every bundled localization.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scripts/walletconnect/reference-dapp-sign.mjs runs the WalletConnect SDK
most dApps ship as a dApp on the live relay. It asks for personal_sign,
eth_signTypedData_v4 and polkadot_signMessage, and checks every signature
with code that is not Fearless's: ox recovers the EVM signer and
@noble/curves verifies the Polkadot ed25519 signature over the <Bytes>
envelope (and that it does not cover the bare message). The SDK and those
libraries stay outside the repository.

WalletConnectLiveSigningTests (skipped unless FEARLESS_WC_SIGN_LIVE=1)
is the wallet: it pairs from the dApp's link, approves an EVM and a
Polkadot account, and answers each request with the app's own request
preparation and signer, as the confirmation does after the PIN.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemiyamakoto takemiyamakoto changed the title iOS 4.2.1 (2026.11.6): make Polkaswap swaps usable again iOS 4.2.1 (2026.11.8): Polkaswap fixes, key-exposure fixes, open-source WalletConnect Nov 8, 2026
takemiyamakoto and others added 10 commits November 8, 2026 14:34
The gate's reviewed test list came in with #1305 already out of step with the
test sources, so the gate could not pass on this line. Replace the nine names
that never existed here, add the 54 tests the selected classes gained, and
require exactly 478 tests. The refreshed list equals the identities that ran
in the Release -O gate on this source: 478 passed, none failed or skipped.

Fix a race in the gate self-test's fake xcrun. Under pipefail, `printf | grep
-q` fails when grep exits before printf finishes writing, so the fake sometimes
answered a tests request with the summary JSON and the valid gate was rejected.

Point the simulator rehearsal at 4.2.1 and baseline the two generator
placeholder comments in the generated TON API client.

Tooling only; nothing here is compiled into the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its checks had never run against this source, and its self-test faked the steps
that were wrong.

Look for managed-object classes among defined symbols instead of external ones.
CDTonDapp and CDTonConnectedApp are internal classes kept alive by
ManagedObjectRuntimeClassRegistry, so `nm -g` can never list them. The fake `nm`
now hides them from -g, so going back to it fails the self-test.

Accept Core Data's complaint about the five transformable attributes that bundled
historical models declare with customClassName="[String]". Those models must stay
byte-exact to open the stores they wrote. Any other attribute, type or failure
line beside it still fails, with cases for each.

Make both Core Data self-tests fail unless they reach their end. An EXIT trap's
own success could hide a crash and report a pass.

Tooling only; nothing here is compiled into the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An iPhone before iOS 26 gives UIActivityViewController no popover controller,
even when asked for the popover style, so there is nothing to anchor. The tests
assumed there always was one. They now accept that on iPhone only; an iPad with
no popover still fails, because presenting one unanchored raises an exception.

Let the seed-share ownership test wait up to 30 s for the system share sheet. It
allowed 3 s, which a loaded machine can exceed, and passes alone in about 2 s.

Tests only. On iOS 18.1 and 27.0 iPhones and an iOS 18.1 iPad: passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The system-share entry on the seed screen is Debug-only, so this test could
only fail at -O. In Release it now asserts that the row offers no such entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Swift 6.4.2 at -O made SolanaTransactionBroadcaster.retry destroy the snapshot
and only then retain record.signature, so the unavailable-recovery outcome
carried a freed string. SolanaSendServiceTests crashed at two tests in every
Release run, and the shipped 2026.11.9 binary has the same order.

No screen reaches this branch today: retry is only offered after an unknown
outcome on a bound record, and an unbound record stops earlier at
unavailableSignature. The behaviour is otherwise unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the stale App Review line, and records the test results, the Release
use-after-free, its fix, the manual-release hold, and what was not run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemiyamakoto takemiyamakoto changed the title iOS 4.2.1 (2026.11.8): Polkaswap fixes, key-exposure fixes, open-source WalletConnect iOS 4.2.1 (2026.11.9): PIN sizing, Polkaswap fixes, key-exposure fixes, open-source WalletConnect Nov 8, 2026
takemiyamakoto and others added 2 commits November 9, 2026 09:08
2026.11.9 carries the Solana retry use-after-free fixed in 46097e1. The owner
chose to replace it in App Review with a build that has the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026.11.10 replaced 2026.11.9 in App Review on 9 November: the build
carries the Solana retry fix, and the owner chose the rebuild over
keeping the queue place. Add its validation, failures and receipts, and
correct the 2026.11.9 note: automatic release was first set at 13:46 UTC,
and load was the probable cause of its two timeouts, not an established one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemiyamakoto takemiyamakoto changed the title iOS 4.2.1 (2026.11.9): PIN sizing, Polkaswap fixes, key-exposure fixes, open-source WalletConnect iOS 4.2.1 (2026.11.10): PIN sizing, Polkaswap fixes, key-exposure fixes, open-source WalletConnect Nov 9, 2026
@takemiyamakoto takemiyamakoto changed the title iOS 4.2.1 (2026.11.10): PIN sizing, Polkaswap fixes, key-exposure fixes, open-source WalletConnect iOS 4.2.1 (2026.11.11): PIN lifecycle fix and wallet release Nov 10, 2026
takemiyamakoto added a commit that referenced this pull request Nov 10, 2026
Brings hotfix/4.2.0-polkaswap-usability from 098dc86 to e61d591, one docs-only
commit (docs/testflight-4.2.1-2026.11.11.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemiyamakoto

Copy link
Copy Markdown
Contributor Author

Folded into #1326, which brings every open iOS PR into master in one change, so one code-owner approval covers it. This PR's branch is kept; new hotfix commits on it should be merged into release/consolidated-20261110 too.

Sign up for free to 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.

1 participant