Skip to content

feat(platform-wallet-ffi)!: let hosts reset an outbound contact account's pool and keep its request digest - #5589

Draft
romchornyi wants to merge 1 commit into
fix/contact-rebuild-keeps-poolfrom
fix/contact-rebuild-ffi-swift
Draft

romchornyi wants to merge 1 commit into
fix/contact-rebuild-keeps-poolfrom
fix/contact-rebuild-ffi-swift

Conversation

@romchornyi

@romchornyi romchornyi commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Basic explanation

What this does: This lets the iOS host store the two things #5587 introduced:

  • the reset that drops a replaced contact account's old addresses;
  • the digest that records which contact request an account was built from.

It adds three optional FFI callbacks, implements them in the Swift persistence handler, and adds one SwiftData property.

Value:

  • Clean replacement. On iOS, a contact who sends a new key gets a clean account. Before, old and new addresses were kept side by side, and the account was replaced again on every launch.
  • No re-check after a restart. A restart knows the account is current without asking Platform.

Risks: Low to medium.

Stack (review and merge in order):

  1. fix(platform-wallet)!: keep a contact's payment account across relaunches and replace it cleanly on rotation #5587: the rule, in Rust, plus SQLite .
  2. feat(platform-wallet-ffi)!: let hosts reset an outbound contact account's pool and keep its request digest #5589: the FFI slots plus Swift storage (this PR).
  3. feat(kotlin-sdk)!: reset an outbound contact account's pool and keep its request digest on Android #5590: JNI plus Kotlin storage (Room v16) and the parity entry. Merge it together with feat(platform-wallet-ffi)!: let hosts reset an outbound contact account's pool and keep its request digest #5589, or right after it: once feat(platform-wallet-ffi)!: let hosts reset an outbound contact account's pool and keep its request digest #5589 is in, the FFI fails a replacement on any host that keeps pools without the reset slot, and the Android host gets that slot only in feat(kotlin-sdk)!: reset an outbound contact account's pool and keep its request digest on Android #5590.

Issue being fixed or feature implemented

Part 2 of the stack started in #5587. The problems on the iOS host:

  • The Swift host keys PersistentCoreAddress rows by address. When a contact rotated, it kept the previous xpub's rows beside the new ones under the same account, and they were restored as one pool.
  • The host never stored which request the account came from.

What was done?

platform-wallet-ffi (persistence.rs, manager.rs)

  • New PersistenceCallbacksExtension slots:

    • on_reset_account_address_pools_fn;
    • on_persist_account_xpub_digest_fn (a null digest clears the stored one);
    • on_load_account_xpub_digest_fn.

    AccountSpecFFI is unchanged.

  • Store order is registrations → digest → reset → pools.

  • The digest is written only on vtables with begin/end, where rounds are atomic.

  • A host that persists pools without the reset slot fails a replacement round rather than keep stale rows.

  • A failed digest read hands over an empty digest instead of failing the load. Rust treats it as "not confirmed".

swift-sdk

  • PersistentAccount.encryptedXpubDigest.
  • Reset deletes the account's PersistentCoreAddress rows. It first unlinks their TXOs, because txos cascades, and registers those TXOs in the round index.
  • A missing account row throws, except for a wallet removed mid-round.

How Has This Been Tested?

  • cargo test -p platform-wallet-ffi --all-features (476). The new tests cover call order, the missing-slot outcomes, non-atomic hosts, null clears and tolerant reads; the extension layout pin is extended. Clippy is clean.
  • swift test (after build_ios.sh --target tests): OutboundAccountReplacementPersistenceTests. The reset keeps TXOs; the digest survives a store reopen and can be cleared. AssetLockOperationPersistenceTests and AddressPoolBulkFetchTests still pass. SwiftExampleApp builds.

Breaking Changes

  • FFI: a host that persists address pools must wire on_reset_account_address_pools_fn, or replacement rounds fail.
  • SwiftData: new property on the unpublished V4.

Checklist:

  • I have performed a self-review of my own code
  • My Rust, FFI, WASM, Swift or Kotlin changes follow the coding conventions
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed
  • If I added or changed GroveDB structure, I described it in the area's structure.rs, regenerated grovedb-structure.json, and checked the structure viewer link posted on this pull request
  • If I added or changed a system contract's document schemas, I checked the contract viewer link posted on this pull request

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

…l and keep its request digest

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYhtAUUCkvoBmp19LA8Z31
@coderabbitai

coderabbitai Bot commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thepastaclaw

Copy link
Copy Markdown
Collaborator

🕓 Review not started yet because this PR is a draft.

  • Request normal review — click when the PR is ready for review.
  • Request priority review — click to move this review to the front of the queue.

Commit 1a414b6. Normal review starts when eligible; priority review starts as soon as a slot is available.

This branch has not been deployed

No deployments
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.

3 participants