Skip to content

Read Wallet on the device - #786

Merged
michaelst merged 1 commit into
finance-kit-ingestfrom
finance-kit-device
Aug 16, 2026
Merged

michaelst merged 1 commit into
finance-kit-ingestfrom
finance-kit-device

Conversation

@michaelst

Copy link
Copy Markdown
Owner

Stacked on #782. Finishes Phase 3.

Pigeon rather than a MethodChannel - the payload is decimal money, dates and enums, and untyped map marshalling is where money bugs breed. FinanceKitPlugin.swift is transport: amounts go up unsigned with a credit/debit indicator beside them, and the server puts the sign on, dedupes, and applies every ledger rule. One place decides which way money went, not two.

Wallet is read on launch and on resume when it is already authorized, and the Banks screen offers "Connect Apple" only where isAvailable() is true - below iOS 17.4 or outside the US, it is not shown at all.

Two things the SDK settled that the plan had guessed at

  • AssetAccount has no assetType. Nothing can tell Apple Cash from Apple Savings without reading the display name, which is exactly the fragile matching the plan ruled out. So assets map to cash and liabilities to credit_card. savings stays in the wire contract - it is a real kind and the server takes it - but nothing emits it. The difference has no behavioural consequence: both are depository accounts, counted in calculate_spendable/1 when synced and unassigned. Only the sub_type label differs.
  • History is per account, and so is its token. There is no currentHistoryToken. The per-account tokens travel together as one base64 JSON blob, which is all the server ever treats history_token as - an opaque string it compares for equality. An account with no entry, a card added since the last read, is read from the beginning while the others resume. Backfill and incremental are the same call with a null token, so read(String?) replaced the plan's two methods.

Also

Removes the sync history button. It only ever meant anything for Plaid, and since #780 the server refuses it for anything else.

Verified

flutter build ios --no-codesign succeeds - the plugin compiles into the real target, which is what proves the project.pbxproj and plugin registration are right. The Swift also type-checks standalone against the iOS 26.5 SDK at an iOS 17.4 deployment target. 88 Dart tests, analyze clean.

Not verified, and cannot be here: FinanceKit has no sandbox and the simulator reports it unavailable. Authorize → backfill → check counts against Wallet → make a purchase → watch the pending charge post in place is a real-device pass that still has to happen.

CI now regenerates the pigeon output and diffs it, the same guarantee the API client already has.

🤖 Generated with Claude Code

Pigeon rather than a MethodChannel: the payload is decimal money, dates and enums, and untyped map
marshalling is where money bugs breed.

The Swift is transport. Amounts go up unsigned with a credit/debit indicator beside them and the
server puts the sign on, so there is one place that decides which way money went. Two things the
SDK settled that the plan had guessed at: there is no `assetType`, so nothing can tell Apple Cash
from Apple Savings without reading the name, which is not worth doing; and history is per account,
so the per-account tokens travel together under one opaque string, which is all the server treats
it as.

Also removes the sync history button. It only ever meant anything for Plaid, and the server now
refuses it for anything else.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@michaelst
michaelst merged commit 9f6f17d into main Aug 16, 2026
6 checks passed
@michaelst
michaelst deleted the finance-kit-device branch August 16, 2026 18:02
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