Skip to content

[Bug]: iOS backup restore reports success but loses profile and payment history #1733

Closed

Description

@piotr-iohk

What happened?

Restoring an iOS-created wallet backup on Android reported WALLET RESTORED, and the Lightning balance returned correctly (499,498 sats), but the saved Pubky profile and payment-request history did not return.

The source iOS wallet had the profile Restore iOS and two Paykit payment-request records, including a manually paid 3,000-sat request marked Proof submitted. After restoration, Android showed Your Name, No payment history, and the profile creation flow instead of the existing profile.

Android logged failures decoding METADATA, SETTINGS, BLOCKTANK and ACTIVITY, then logged Full restore success. Ordinary Lightning transactions were visible, but without their restored contact labels. This report does not claim loss of the Bitcoin balance or a duplicate payment.

Expected behavior

A supported cross-platform backup restores the profile, contacts/payment-request history and compatible wallet data alongside the balance. If a category cannot be restored, show that restoration is incomplete and identify the failed data instead of displaying unconditional success.

Steps to Reproduce

  1. On iOS, create a regtest wallet and Pubky profile. Link it to a separate contact wallet and fund a Lightning channel.
  2. Exchange payment requests/payments so the iOS wallet has history. In this run it received 2,500 sats and manually paid a 3,000-sat request, with 499,498 sats remaining.
  3. Wait for the iOS data backups to complete. Record the recovery phrase privately.
  4. Reset the source iOS wallet before restoring elsewhere; do not leave the same wallet or Pubky identity active on two installations.
  5. On a cleared Android installation, restore that iOS wallet from its recovery phrase and finish onboarding.
  6. Inspect the balance, Profile, and Subscriptions → Payments. Compare with the source profile/history and the Android restore logs.

Control: restoring the same iOS backup on iOS had retained the balance and paid request before the cross-platform attempt. Android-to-Android allowance restoration also passed separately.

Logs / Screenshots / Recordings

The scoped Android log contains:

10-30 09:17:35.362  1267  3113 D APP     : 2026-10-30 08:17:35.362 DEBUG   [BackupRepo.kt:863]                  Full restore starting - BackupRepo
10-30 09:17:35.677  1267  1305 W APP     : 2026-10-30 08:17:35.676 WARN    [BackupRepo.kt:1243]                 Failed to restore: 'METADATA' [MissingFieldException='Fields [txId, channelId] are required for type with serial name 'com.synonym.bitkitcore.PreActivityMetadata', but they were missing at path: $.tagMetadata[0]'] - BackupRepo
10-30 09:17:35.721  1267  1305 W APP     : 2026-10-30 08:17:35.721 WARN    [BackupRepo.kt:1243]                 Failed to restore: 'SETTINGS' [JsonDecodingException='Unexpected JSON token at offset 170: Expected start of the array '[', but had '"' instead at path: $.settings.addressTypesToMonitor
10-30 09:17:37.431  1267  3292 W APP     : 2026-10-30 08:17:37.430 WARN    [BackupRepo.kt:1243]                 Failed to restore: 'BLOCKTANK' [JsonDecodingException='Unexpected JSON token at offset 631: Expected beginning of the string, but got { at path: $.info.onchain.network
10-30 09:17:37.480  1267  1295 W APP     : 2026-10-30 08:17:37.480 WARN    [BackupRepo.kt:1243]                 Failed to restore: 'ACTIVITY' [JsonDecodingException='Class discriminator was missing and no default serializers were registered in the polymorphic scope of 'Activity'.
10-30 09:17:37.481  1267  1295 I APP     : 2026-10-30 08:17:37.481 INFO    [BackupRepo.kt:923]                  Full restore success - BackupRepo

Accessibility snapshots captured before/after restore confirm:

  • iOS before restore: payment-request rows for 3,000 sats sent and 2,500 sats received; the sent request has Proof submitted and note QA1164.
  • Android after restore: NO PAYMENT HISTORY; Profile opens PORTABLE PROFILE, then offers NEW PUBKY / Create profile with Bitkit.

Android offers profile onboarding after restoring the source wallet that already had a profile:

Android profile onboarding after iOS wallet restore; existing profile is absent

The exact scoped log is included above; source/destination accessibility observations are summarized above. No recording was captured. The full local snapshots remain available for follow-up.

Bitkit Version

Both CI artifact merge trees were verified identical to the respective PR head trees.

Device / OS

  • Destination: existing Pixel_6 Android emulator, Android 13.
  • Source: existing iPhone 17 simulator, iOS 26.0.

Reproducibility

Observed once in one iOS → Android restore attempt. No repeat-rate claim; not yet reproduced on Android master or a released build.

Additional context

  • Backend: local Docker regtest, Electrum, LND and Pubky 0.14.0; local Homegate adapter for signup; CI-default staging VSS/auth for actual backups. Separate wallets and Pubky identities were used for payments, and the source installation was reset before moving its wallet.
  • The failure occurs on the Android reader. Whether the shared-format correction belongs in the iOS writer, Android reader, or both still needs investigation.
  • At the tested Android head, BackupRepo.restoreMetadataBackup decodes the full MetadataBackupV1 before calling pubkyRepo.restoreSessionBackupState. The missing-field exception occurs before the profile restore call. This method is unchanged from fix: keep allowance history across a wallet restore #1708's base, a56c75be32ed727ac71f16fd5b837cc3cff80c46; that alone does not prove when the bug was introduced. See the pinned restore path.
  • The allowance-specific WALLET restore logged success; the missing profile prevented validating the iOS-origin request/allowance UI. This is not established as an allowance wire-format defect or a regression introduced by fix: keep allowance history across a wallet restore #1708 or iOS fix: consume vss-client 0.5.23 #1164. Track it separately and link it from fix: keep allowance history across a wallet restore #1708's device results.
  • Related historical work: Hardware Wallet Data Backup & Restore #1046 (closed), which covers Core-owned backup field migration. This report concerns the observed iOS-produced payload failures and misleading restore-success result, not just missing walletId migration.

Acceptance: repeat iOS → Android restoration with profile, contact metadata, automatic and manual payment history; verify all expected data and balances survive. Add fixture coverage for the reported field/type mismatches and verify category failures cannot produce an unconditional success result.

Activity

  1. added theissue type on Oct 30, 2026
  2. ovitrif commented on Oct 30, 2026

    @ovitrif
    Collaborator

    Triage: 3.2.0. The iOS-to-Android restore gap reproduces on 3.0.1 builds, so it is not a 3.1.0 regression, and no PR fixes it yet; 3.1.0 is down to its cut-line PRs (https://synonymworkspace.slack.com/archives/C07BJ7DNPCG/p1793307568629859). It can move into 3.1.0 if a fix lands before the RC.

  3. added this to the 3.2.0 milestone on Oct 30, 2026
  4. ovitrif commented on Oct 30, 2026

    @ovitrif
    Collaborator

    Moving this issue to 3.1.0: a fix is in progress for it, and the 3.1.0 cut now takes fixes merged over the weekend, before the RC on Monday 2 Nov.

  5. modified the milestones: 3.2.0, 3.1.0 on Oct 30, 2026
  6. self-assigned this
    on Oct 30, 2026
  7. ovitrif commented on Nov 2, 2026

    @ovitrif
    Collaborator

    Fixed by #1736.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions