Skip to content

✨ app: add wallet extension infrastructure#1155

Open
aguxez wants to merge 4 commits into
mainfrom
app-extensions
Open

✨ app: add wallet extension infrastructure#1155
aguxez wants to merge 4 commits into
mainfrom
app-extensions

Conversation

@aguxez

@aguxez aguxez commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the dependencies, native targets, shared storage bridge, issuer configuration, entitlements, and Expo/Xcode integration required by the Exa Wallet extensions.

The Card-screen provisioning flow is intentionally kept in the dependent provisioning PR.

Commits

  • Add MeaWallet MPP SDK dependency
  • Add Apple target tooling
  • Add MeaWallet configuration assets
  • Add Wallet extension infrastructure

Summary by CodeRabbit

  • New Features
    • Added Apple Wallet provisioning for wallet extensions, including an authorization flow and a non-UI issuer experience for card pass entry generation.
    • Introduced secure persistence for extension tokens and card provisioning snapshots, with safe JS fallbacks when native support isn’t available.
    • Added automatic generation of the card signature PNG asset during builds.
  • Build & Configuration
    • Wired wallet configuration assets into both iOS and Android builds and updated app extension setup with required entitlements.
    • Updated build tooling defaults and production environment settings.

@changeset-bot

changeset-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a10eea3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@exactly/mobile Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds Apple Wallet issuer and authorization extensions with shared native storage, MPP provisioning integration, generated wallet assets, and Expo iOS/Android build configuration.

Changes

Wallet provisioning

Layer / File(s) Summary
Wallet storage bridge
src/utils/walletExtensionStorage.ts, modules/wallet-extension-storage/ios/*
Adds React Native wrappers and iOS Keychain/app-group persistence for wallet tokens and card snapshots.
Issuer extension provisioning flow
src/issuerNonUIExtension.ts
Registers the issuer extension, validates stored context, fetches provisioning data, initializes Apple Pay tokenization, and returns eligible card entries.
Wallet extension targets
targets/ExaWalletExtension/*, targets/ExaWalletAuthExtension/*
Adds target metadata, entitlements, PassKit configuration, authorization handling, and CocoaPods dependencies.
Expo native build integration
app.config.ts, src/assets/mea_config
Configures extension entitlements, asset resources, Podfile patches, Xcode targets, Android Gradle settings, manifest metadata, and private Maven access.
MPP package and build assets
package.json, patches/*, .npmrc, eas.json, .changeset/*, cspell.json
Adds MPP tooling and patching, card signature generation, registry/build settings, wallet assets, spelling configuration, and a patch release record.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AppRegistry
  participant ExaIssuerExtensionHandler
  participant WalletExtensionStorage
  participant ProvisioningAPI
  participant MeaPushProvisioning
  AppRegistry->>ExaIssuerExtensionHandler: Render issuer extension
  ExaIssuerExtensionHandler->>WalletExtensionStorage: Load token and snapshot
  ExaIssuerExtensionHandler->>ProvisioningAPI: Fetch provisioning secrets
  ExaIssuerExtensionHandler->>MeaPushProvisioning: Initialize Apple Pay tokenization
  MeaPushProvisioning-->>ExaIssuerExtensionHandler: Return tokenization data
  ExaIssuerExtensionHandler-->>AppRegistry: Return eligible card entry
Loading

Suggested reviewers: cruzdanilo, dieguezguille, nfmelendez

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding wallet extension infrastructure to the app.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch app-extensions
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch app-extensions

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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request integrates MeaWallet configurations and introduces a new shared storage module (WalletExtensionStorage) along with iOS wallet extensions. Feedback on the changes highlights several critical issues: a potential runtime crash in issuerNonUIExtension.ts when accessing properties on a null snapshot, a potential Objective-C crash in WalletExtensionStorage.m from nil values in a dictionary literal, a fragile string matching check in app.config.ts that could duplicate pod insertions, a reliability issue with dynamic node execution in pods.rb, and a security risk concerning hardcoded repository credentials in app.config.ts.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/issuerNonUIExtension.ts Outdated
Comment thread modules/wallet-extension-storage/ios/WalletExtensionStorage.m
Comment thread app.config.ts Outdated
Comment thread targets/ExaWalletExtension/pods.rb
Comment thread app.config.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 103e84d9-d5e8-47a5-8772-6a397e551874

📥 Commits

Reviewing files that changed from the base of the PR and between 53ff381 and b9d3ad3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (21)
  • .changeset/rich-months-double.md
  • .npmrc
  • app.config.ts
  • cspell.json
  • eas.json
  • modules/wallet-extension-storage/ios/WalletExtensionStorage.m
  • modules/wallet-extension-storage/ios/WalletExtensionStorage.podspec
  • package.json
  • patches/@meawallet__react-native-mpp.patch
  • src/assets/mea_config
  • src/issuerNonUIExtension.ts
  • src/utils/walletExtensionStorage.ts
  • targets/ExaWalletAuthExtension/ExaWalletAuthExtension.entitlements
  • targets/ExaWalletAuthExtension/ExaWalletAuthExtension.swift
  • targets/ExaWalletAuthExtension/Info.plist
  • targets/ExaWalletAuthExtension/expo-target.config.js
  • targets/ExaWalletExtension/ExaWalletExtension.entitlements
  • targets/ExaWalletExtension/ExaWalletExtension.m
  • targets/ExaWalletExtension/Info.plist
  • targets/ExaWalletExtension/expo-target.config.js
  • targets/ExaWalletExtension/pods.rb

Comment thread .npmrc
Comment thread app.config.ts
Comment thread modules/wallet-extension-storage/ios/WalletExtensionStorage.m
Comment thread src/issuerNonUIExtension.ts
Comment thread targets/ExaWalletExtension/Info.plist Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 98592aef-5cf4-45c7-a176-18390e73da4f

📥 Commits

Reviewing files that changed from the base of the PR and between b9d3ad3 and 1712771.

📒 Files selected for processing (16)
  • app.config.ts
  • modules/wallet-extension-storage/ios/WalletExtensionStorage.m
  • modules/wallet-extension-storage/ios/WalletExtensionStorage.podspec
  • package.json
  • patches/@meawallet__react-native-mpp.patch
  • src/issuerNonUIExtension.ts
  • src/utils/walletExtensionStorage.ts
  • targets/ExaWalletAuthExtension/ExaWalletAuthExtension.entitlements
  • targets/ExaWalletAuthExtension/ExaWalletAuthExtension.swift
  • targets/ExaWalletAuthExtension/Info.plist
  • targets/ExaWalletAuthExtension/expo-target.config.js
  • targets/ExaWalletExtension/ExaWalletExtension.entitlements
  • targets/ExaWalletExtension/ExaWalletExtension.m
  • targets/ExaWalletExtension/Info.plist
  • targets/ExaWalletExtension/expo-target.config.js
  • targets/ExaWalletExtension/pods.rb

Comment thread app.config.ts
Comment thread app.config.ts Outdated
Comment thread app.config.ts
Comment thread src/utils/walletExtensionStorage.ts Outdated
Comment thread targets/ExaWalletAuthExtension/ExaWalletAuthExtension.swift
Comment thread targets/ExaWalletExtension/Info.plist

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/utils/walletExtensionStorage.ts (1)

26-44: 🛠️ Refactor suggestion | 🟠 Major

Shorten the storage helper names and drop the object unpacking.

As per coding guidelines, do not repeat the module name in its members and avoid unpacking fields only to pass them individually. This was flagged in a previous review.

  • src/utils/walletExtensionStorage.ts#L26-L44: Rename these exports to clear, saveToken, saveSnapshot, getToken, and getSnapshot. Pass token and expire as separate arguments instead of an object.
  • src/issuerNonUIExtension.ts#L11-L11: Update the imports to use the shortened names.
  • src/issuerNonUIExtension.ts#L103-L104: Call the updated functions.
♻️ Proposed refactor for the storage utilities
-export function clearWalletExtensionStorage() {
+export function clear() {
   return native?.clearWalletExtensionStorage() ?? Promise.resolve();
 }
 
-export function saveWalletExtensionToken({ token, expire }: { expire: number; token: string }) {
+export function saveToken(token: string, expire: number) {
   return native?.saveWalletExtensionToken(token, expire) ?? Promise.resolve();
 }
 
-export function saveCardProvisioningSnapshot(snapshot: CardProvisioningSnapshot) {
+export function saveSnapshot(snapshot: CardProvisioningSnapshot) {
   return native?.saveCardProvisioningSnapshot(snapshot) ?? Promise.resolve();
 }
 
-export function getWalletExtensionToken() {
+export function getToken() {
   return native?.getWalletExtensionToken() ?? Promise.resolve(null);
 }
 
-export function getCardProvisioningSnapshot() {
+export function getSnapshot() {
   return native?.getCardProvisioningSnapshot() ?? Promise.resolve(null);
 }

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4ade7f83-e7c1-45c5-9d29-59a980bdc6bf

📥 Commits

Reviewing files that changed from the base of the PR and between 1712771 and b5a2c7a.

📒 Files selected for processing (16)
  • app.config.ts
  • modules/wallet-extension-storage/ios/WalletExtensionStorage.m
  • modules/wallet-extension-storage/ios/WalletExtensionStorage.podspec
  • package.json
  • patches/@meawallet__react-native-mpp.patch
  • src/issuerNonUIExtension.ts
  • src/utils/walletExtensionStorage.ts
  • targets/ExaWalletAuthExtension/ExaWalletAuthExtension.entitlements
  • targets/ExaWalletAuthExtension/ExaWalletAuthExtension.swift
  • targets/ExaWalletAuthExtension/Info.plist
  • targets/ExaWalletAuthExtension/expo-target.config.js
  • targets/ExaWalletExtension/ExaWalletExtension.entitlements
  • targets/ExaWalletExtension/ExaWalletExtension.m
  • targets/ExaWalletExtension/Info.plist
  • targets/ExaWalletExtension/expo-target.config.js
  • targets/ExaWalletExtension/pods.rb

Comment thread app.config.ts Outdated
Comment thread app.config.ts Outdated
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.94%. Comparing base (53ff381) to head (b5a2c7a).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1155   +/-   ##
=======================================
  Coverage   72.94%   72.94%           
=======================================
  Files         254      254           
  Lines       10747    10747           
  Branches     3557     3557           
=======================================
  Hits         7839     7839           
  Misses       2624     2624           
  Partials      284      284           
Flag Coverage Δ
e2e 72.94% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3995971a-fa2e-4439-b1c7-18a43912597f

📥 Commits

Reviewing files that changed from the base of the PR and between b5a2c7a and 3db51ad.

📒 Files selected for processing (16)
  • app.config.ts
  • modules/wallet-extension-storage/ios/WalletExtensionStorage.m
  • modules/wallet-extension-storage/ios/WalletExtensionStorage.podspec
  • package.json
  • patches/@meawallet__react-native-mpp.patch
  • src/issuerNonUIExtension.ts
  • src/utils/walletExtensionStorage.ts
  • targets/ExaWalletAuthExtension/ExaWalletAuthExtension.entitlements
  • targets/ExaWalletAuthExtension/ExaWalletAuthExtension.swift
  • targets/ExaWalletAuthExtension/Info.plist
  • targets/ExaWalletAuthExtension/expo-target.config.js
  • targets/ExaWalletExtension/ExaWalletExtension.entitlements
  • targets/ExaWalletExtension/ExaWalletExtension.m
  • targets/ExaWalletExtension/Info.plist
  • targets/ExaWalletExtension/expo-target.config.js
  • targets/ExaWalletExtension/pods.rb

Comment thread app.config.ts
Comment thread package.json
Comment thread src/issuerNonUIExtension.ts Outdated
Comment thread src/issuerNonUIExtension.ts
Comment thread targets/ExaWalletExtension/pods.rb
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