(feat) [ONR-511] Migration to Nitro Modules#1
Merged
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Install react-native-nitro-modules@0.35.9 (peerDep) + nitrogen@0.35.9 (devDep) - Add nitro.json config with onramper namespace - Add nitrogen codegen script - Podspec: remove ExpoModulesCore dep, narrow source_files to Hybrid*.swift/Nitro*.swift - Delete expo-module.config.json (Expo autolinking manifest)
…native.config.js - src/specs/OnramperNitro.nitro.ts + nitrogen-generated specs - ios/HybridOnramperNitro.swift (Promise.async) - nitro.json autolinking (0.35.9 ios.implementationClassName form) - react-native.config.js (package) + example-bare/react-native.config.js (consumer, explicit root+podspecPath) so RN-CLI autolinks the package through the file:.. symlink - pod install links both NitroModules + OnramperReactNative Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ense :file - package-side react-native.config.js used dependency.platforms.ios.podspecPath, which RN 0.85 CLI rejects as invalid (warns on every launch). The example links via the consumer-side example-bare/react-native.config.js instead. Real-consumer (npm-install) autolinking to be validated in Phase 4. - podspec license dropped the unreadable ../LICENSE :file reference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RN 0.81+ defaults to a precompiled React Native Core whose distribution doesn't expose module maps for Swift, causing 'No such module React' in the stock AppDelegate.swift and our Nitro pod (cascading to HybridOnramperNitroSpec not in scope). Set ENV in the Podfile to build RN core from source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…resolve nitrogen's add_nitrogen_files appends source globs (nitrogen/generated/**) relative to the podspec dir. With the podspec in ios/, those resolved to ios/nitrogen/** (nonexistent), so the generated HybridOnramperNitroSpec.swift was never compiled -> 'cannot find type HybridOnramperNitroSpec in scope'. Moved podspec to repo root (Nitro convention); ios/-prefixed our own sources. Also includes example-bare Podfile SWIFT_ENABLE_EXPLICIT_MODULES=NO fix (Xcode 26 explicit modules -> module map not found) and consumer config podspecPath update. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sh nitrogen output Validated empirically (prebuilt-core ON + explicit-modules OFF builds clean): SWIFT_ENABLE_EXPLICIT_MODULES=NO is the sole required RN0.85/Xcode26 fix — it also resolves the earlier 'No such module React', so the faster precompiled React Native Core can stay enabled. Removed the source-build override. package.json files: add nitrogen/generated + the root OnramperReactNative.podspec so real npm consumers get the generated specs and podspec. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- #2 sdkProbe(): import OnramperSDK, construct a real Environment value — proves
the vendored xcframework links under Nitro's Swift/C++ interop.
- #3 HybridNitroSpikeView: a Nitro View hosting SwiftUI via UIHostingController
(Phase 2's checkout-button pattern). View spec scoped to { ios: 'swift' } since
Nitro views otherwise demand a Kotlin impl too.
- #4 startTicker/stopTicker: stores a JS callback natively + fires on a timer
(event-stream mechanism); stopTicker releases it (cleanup path).
- podspec: add install_modules_dependencies(s) for RN new-arch Fabric/Yoga
header paths (Nitro view pulls in React-Fabric -> yoga/style/Style.h).
Verified: BUILD SUCCEEDED on iOS simulator.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ble in dark mode Spike gate passed on device: proofs #1-#4 all confirmed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + events + session Replaces the Expo Modules bridge with a Nitro HybridObject wrapping OnramperSDK.OnramperClient, designed against the SDK (not the Expo-era bridge): - HybridOnramperNitro.swift: wraps OnramperClient; mirrors $state (Combine) and the events AsyncStream to single JS callbacks; feeds sessionExpirationHandler directly from a stored Nitro async callback (drops the token/continuation dance). - OnramperSDKBridge.swift: SDK enum -> JS dict mapping + JSON-string transport (OnramperState/CheckoutEvent are non-Codable); error code/info, no [info:] folding. - OnramperClient.ts: same public API (initialize/reset/signOut/addStateListener/ addEventListener/destroy); per-client native instance; JSON parsed to typed unions. - errors.ts: dropped the Expo message-folding regex. - Removed spike code + the Expo checkout view (returns as a Nitro view in Phase 2). - package.json: source/react-native field so the example bundles from src. Verified: BUILD SUCCEEDED on iOS simulator. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- new react-native-nitro-modules mock (per-instance createHybridObject capturing the registered state/event/session callbacks); drop the expo-modules-core mock. - OnramperClient.test: cover configure/initialize/signOut, session-handler resolve+reject, state/event fan-out, and destroy()->dispose(). 12 passing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uirements
- OnramperCheckoutButton Nitro view (HybridOnramperCheckoutButton.swift) hosts the
SDK's SwiftUI OnramperCheckoutButton via UIHostingController, consumed from
PreparedIntentRegistry.shared by handle; re-attaches as a child VC so the button
can present its login/webview sheets.
- getCheckoutRequirements/cancelPreparedIntent on HybridOnramperNitro: decode the
JSON request/style (OnramperCheckoutBridge.swift), call the SDK, stash the button
by ULID handle, return { intentHandle, quoteJson }.
- PreparedIntentRegistry: shared singleton (module stores, view consumes by handle).
- OnramperClient.ts: getCheckoutRequirements (returns a button element + quote) +
cancelPreparedIntent restored; OnramperCheckoutButtonView re-added as a Nitro view.
- Deleted all remaining legacy Expo Swift (module + view + Bridging/*); podspec
source_files simplifies to ios/*.swift. tsconfig: resolveJsonModule for the
generated view config.
Verified: BUILD SUCCEEDED on iOS simulator; typecheck/lint/jest(12) green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The current OnramperSDK adds 5 provider-lifecycle events (providerReady, paymentAuthorized, paymentProcessing, paymentCancelled, providerError) emitted by third-party checkout webviews. Map them in OnramperSDKBridge.toJSDict() + add them to the typed CheckoutEvent union. Surfaced by rebuilding the xcframework from the current onramper-sdk source (which also carries the ff29281 App Attest self-heal). Note: the vendored xcframework is gitignored (fetched per release); this commit is the wrapper-side event handling. A proper SDK release should ship the new binary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the last loose `response: unknown` with CheckoutFinalizeResponse / HeadlessCheckoutData mirrored from Sources/OnramperSDK/Models/CheckoutFinalizeResponse.swift, and export them. (errors.ts info stays Record<string,unknown> — genuinely open-ended.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
app.plugin.js applies the two iOS requirements that aren't Expo defaults: - ios.deploymentTarget 16.4 (vendored OnramperSDK.xcframework requires it) - SWIFT_ENABLE_EXPLICIT_MODULES=NO (Xcode 16+/26 + CocoaPods + Swift pods) Registered in package.json files; @expo/config-plugins as a devDep. example/ (Expo) wired to consume the Nitro package: react-native-nitro-modules dep, newArchEnabled, the plugin in app.json, bundle id com.onramper.demo.react-native-expo (distinct from the bare example so both coexist on-device), prebuilt + BUILD SUCCEEDED. Notable: Expo autolinking discovers the package's root podspec automatically — no consumer react-native.config.js needed (unlike the bare RN-CLI + file:.. symlink case). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The example consumes the package via file:.., and Metro's symlink-dedup config (disableHierarchicalLookup + nodeModulesPaths=[example/node_modules]) requires the Nitro peer dep to be physically in example/node_modules. Installed with --legacy-peer-deps (pre-existing @react-native/new-app-screen 0.85.2-vs-0.85.3 peer mismatch) + --ignore-scripts (the file:.. package's expo-module prepare otherwise clobbers tsconfig.json + fails). Restores tsconfig resolveJsonModule. NOTE: expo-module-scripts' prepare regenerating tsconfig.json is fragile — Phase 4 should drop expo-module-scripts (→ plain tsc) to stop the clobbering. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Public-facing docs were still written for the Expo Modules era. Updated to the Nitro reality: - Install: react-native-nitro-modules peer dep + New Architecture; bare RN and Expo (via the bundled config plugin) — dropped install-expo-modules and the mandatory ExpoReactNativeFactory AppDelegate section entirely. - iOS setup: bare-RN Podfile (deployment target 16.4 + SWIFT_ENABLE_EXPLICIT_MODULES=NO); Metro/Babel use standard RN defaults for bare RN. - Events: documented the 5 provider-lifecycle events; removed the obsolete 'checkoutCancelled not surfaced' + per-view-handler caveats. - Cleanups: dropped the objectVersion sed workaround, fixed the file:.. symlink contributor note (Nitro module names + bare-RN autolinking), converted the going-live checklist to plain bullets (no checkbox/todo rendering). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR migrates the library from an Expo Modules–based native bridge to Nitro Modules/Nitrogen-generated HybridObjects, enabling consumption in bare React Native (without Expo) while keeping an Expo integration path via a config plugin.
Changes:
- Replaces the Expo Modules native module/event emitter with a per-
OnramperClientNitro HybridObject + single-callback state/event streams. - Adds Nitro/Nitrogen specs and generated bridge code (C++/Swift), plus a root podspec for New Architecture builds.
- Updates packaging/docs/examples/tests to depend on
react-native-nitro-modules, include generated artifacts, and support Expo prebuild viaapp.plugin.js.
Reviewed changes
Copilot reviewed 86 out of 144 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Enables JSON module imports and includes Nitrogen-generated JSON in TS compilation. |
| src/types.ts | Adds typed CheckoutFinalizeResponse/HeadlessCheckoutData surfaced through events. |
| src/specs/OnramperNitro.nitro.ts | Defines the Nitro HybridObject surface (configure/init/state+event listeners/session handler). |
| src/specs/OnramperCheckoutButton.nitro.ts | Defines the Nitro-hosted native checkout button view props. |
| src/OnramperNative.ts | Replaces Expo requireNativeModule with NitroModules.createHybridObject(...). |
| src/OnramperClient.ts | Reworks JS client to own a native HybridObject instance and parse/fan-out JSON callbacks. |
| src/OnramperCheckoutButtonView.tsx | Replaces Expo view manager with Nitro getHostComponent(...) + generated view config JSON. |
| src/index.ts | Exports new finalize/checkout response types. |
| src/events.ts | Types checkoutFinalized and adds provider lifecycle events. |
| src/errors.ts | Simplifies OnramperError.from for structured {code,message,info} errors. |
| README.md | Updates install/requirements/docs for Nitro + New Architecture + Expo plugin usage. |
| package.json | Switches deps/peers to Nitro, publishes generated artifacts, adds root entry points. |
| OnramperReactNative.podspec | New root podspec integrating Nitrogen-generated files + RN new-arch deps. |
| nitrogen/generated/shared/json/OnramperCheckoutButtonConfig.json | Generated host component config for the Nitro view. |
| nitrogen/generated/shared/c++/views/HybridOnramperCheckoutButtonComponent.hpp | Generated Fabric component definitions for the Nitro view. |
| nitrogen/generated/shared/c++/views/HybridOnramperCheckoutButtonComponent.cpp | Generated Fabric component implementation for the Nitro view. |
| nitrogen/generated/shared/c++/PreparedIntentResult.hpp | Generated C++ struct for prepared intent results (handle + quote JSON). |
| nitrogen/generated/shared/c++/OnramperNitroConfig.hpp | Generated C++ struct for Nitro configuration. |
| nitrogen/generated/shared/c++/NitroSessionCredentials.hpp | Generated C++ struct for session credentials returned by JS handler. |
| nitrogen/generated/shared/c++/HybridOnramperNitroSpec.hpp | Generated C++ HybridObject spec for the Nitro module. |
| nitrogen/generated/shared/c++/HybridOnramperNitroSpec.cpp | Generated HybridObject method registration. |
| nitrogen/generated/shared/c++/HybridOnramperCheckoutButtonSpec.hpp | Generated C++ HybridView spec for the checkout button. |
| nitrogen/generated/shared/c++/HybridOnramperCheckoutButtonSpec.cpp | Generated HybridView method/property registration. |
| nitrogen/generated/ios/swift/PreparedIntentResult.swift | Generated Swift typealias/bridging for PreparedIntentResult. |
| nitrogen/generated/ios/swift/OnramperNitroConfig.swift | Generated Swift typealias/bridging for config struct. |
| nitrogen/generated/ios/swift/NitroSessionCredentials.swift | Generated Swift typealias/bridging for credentials struct. |
| nitrogen/generated/ios/swift/HybridOnramperNitroSpec.swift | Generated Swift protocol/base wiring for the Nitro HybridObject. |
| nitrogen/generated/ios/swift/HybridOnramperCheckoutButtonSpec.swift | Generated Swift protocol/base wiring for the Nitro HybridView. |
| nitrogen/generated/ios/swift/HybridOnramperCheckoutButtonSpec_cxx.swift | Generated Swift↔C++ wrapper for the HybridView. |
| nitrogen/generated/ios/swift/Func_void.swift | Generated closure wrapper for Swift→C++ bridging. |
| nitrogen/generated/ios/swift/Func_void_std__string.swift | Generated closure wrapper for string callback bridging. |
| nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_NitroSessionCredentials__.swift | Generated closure wrapper for promise bridging. |
| nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift | Generated closure wrapper for error bridging. |
| nitrogen/generated/ios/swift/Func_void_PreparedIntentResult.swift | Generated closure wrapper for PreparedIntentResult bridging. |
| nitrogen/generated/ios/swift/Func_void_NitroSessionCredentials.swift | Generated closure wrapper for credentials bridging. |
| nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_NitroSessionCredentials____.swift | Generated wrapper for nested promise callback return bridging. |
| nitrogen/generated/ios/OnramperReactNativeAutolinking.swift | Generated Swift factory functions used by Nitro autolinking. |
| nitrogen/generated/ios/OnramperReactNativeAutolinking.mm | Generated ObjC++ registration into Nitro HybridObjectRegistry. |
| nitrogen/generated/ios/OnramperReactNative+autolinking.rb | Generated podspec helper adding Nitrogen sources/flags/deps. |
| nitrogen/generated/ios/OnramperReactNative-Swift-Cxx-Umbrella.hpp | Generated umbrella header for Swift/C++ bridging. |
| nitrogen/generated/ios/OnramperReactNative-Swift-Cxx-Bridge.cpp | Generated C++ glue for Swift closure/type bridging. |
| nitrogen/generated/ios/c++/views/HybridOnramperCheckoutButtonComponent.mm | Generated iOS Fabric component view holder implementation. |
| nitrogen/generated/ios/c++/HybridOnramperNitroSpecSwift.hpp | Generated C++ wrapper calling into Swift implementation. |
| nitrogen/generated/ios/c++/HybridOnramperNitroSpecSwift.cpp | Generated C++ wrapper compilation unit. |
| nitrogen/generated/ios/c++/HybridOnramperCheckoutButtonSpecSwift.hpp | Generated C++ wrapper for the HybridView calling into Swift. |
| nitrogen/generated/ios/c++/HybridOnramperCheckoutButtonSpecSwift.cpp | Generated C++ wrapper compilation unit. |
| nitrogen/generated/.gitattributes | Marks generated files for GitHub linguist. |
| nitro.json | Adds Nitro config and autolinking declarations for HybridObject/HybridView. |
| jest.config.js | Switches Jest module mapping from Expo to Nitro module mock. |
| ios/PreparedIntentRegistry.swift | Introduces a process-wide registry singleton to share prepared intents across HybridObjects/HybridViews. |
| ios/OnramperSDKBridge.swift | Adds SDK→JS JSON mapping for state/events/errors for Nitro callback transport. |
| ios/OnramperReactNativeModule.swift | Removes Expo Modules native module implementation. |
| ios/OnramperReactNative.podspec | Removes the old ios/-scoped ExpoModulesCore-based podspec. |
| ios/OnramperCheckoutButtonView.swift | Removes the old Expo view manager host. |
| ios/OnramperCheckoutBridge.swift | Adds JSON decoding logic for request/button style into SDK structures. |
| ios/HybridOnramperNitro.swift | Adds Swift Nitro HybridObject implementing the new bridge. |
| ios/HybridOnramperCheckoutButton.swift | Adds Swift Nitro HybridView hosting the SDK SwiftUI button. |
| ios/Bridging/SessionCredentialsDict.swift | Removes Expo Record-based bridging type. |
| ios/Bridging/PreparedIntentDict.swift | Removes Expo Record-based bridging type. |
| ios/Bridging/OnramperState+Dict.swift | Removes old Expo-specific state mapping helpers. |
| ios/Bridging/OnramperError+JSError.swift | Removes old Expo-specific error mapping helpers. |
| ios/Bridging/OnramperConfigurationDict.swift | Removes old Expo Record-based config bridging. |
| ios/Bridging/CheckoutRequestDict.swift | Removes old Expo Record-based request bridging. |
| ios/Bridging/CheckoutEvent+Dict.swift | Removes old Expo-specific event mapping helpers. |
| ios/Bridging/CheckoutButtonStyleDict.swift | Removes old Expo Record-based style bridging. |
| expo-module.config.json | Removes Expo module manifest config (no longer Expo Modules-based). |
| example/package.json | Adds react-native-nitro-modules to the Expo example app deps. |
| example/package-lock.json | Locks added Nitro dependency in the Expo example app. |
| example/ios/Podfile.properties.json | Adjusts example iOS Podfile properties. |
| example/ios/Podfile.lock | Updates pods to include NitroModules and new podspec path. |
| example/ios/Podfile | Disables explicit Swift modules to fix Xcode 16+/26 build issues. |
| example/ios/OnramperReactNativeExample/PrivacyInfo.xcprivacy | Updates privacy manifest entries. |
| example/ios/OnramperReactNativeExample/Info.plist | Reformats + updates URL scheme/bundle identifier values. |
| example/app.json | Enables new arch and applies the package Expo config plugin. |
| example-bare/tsconfig.json | Adds TS config for new bare RN example app. |
| example-bare/README.md | Adds generated bare RN template README. |
| example-bare/react-native.config.js | Adds explicit autolinking config for local file:.. consumption. |
| example-bare/package.json | Adds a new bare RN example app consuming the library via file:... |
| example-bare/metro.config.js | Configures Metro for monorepo-style watchFolders and resolution. |
| example-bare/jest.config.js | Adds Jest config for bare RN example app. |
| example-bare/ios/Podfile | Adds iOS setup + explicit Swift modules disable workaround. |
| example-bare/ios/OnramperBare/PrivacyInfo.xcprivacy | Adds privacy manifest for bare RN example. |
| example-bare/ios/OnramperBare/OnramperBare.entitlements | Adds entitlements file for bare RN example. |
| example-bare/ios/OnramperBare/LaunchScreen.storyboard | Adds launch screen storyboard for bare RN example. |
| example-bare/ios/OnramperBare/Info.plist | Adds iOS Info.plist for bare RN example. |
| example-bare/ios/OnramperBare/Images.xcassets/Contents.json | Adds asset catalog boilerplate. |
| example-bare/ios/OnramperBare/Images.xcassets/AppIcon.appiconset/Contents.json | Adds app icon set metadata. |
| example-bare/ios/OnramperBare/AppDelegate.swift | Adds iOS AppDelegate for bare RN new-arch app. |
| example-bare/ios/OnramperBare.xcworkspace/contents.xcworkspacedata | Adds workspace definition for bare RN example. |
| example-bare/ios/OnramperBare.xcodeproj/xcshareddata/xcschemes/OnramperBare.xcscheme | Adds shared Xcode scheme for bare RN example. |
| example-bare/ios/.xcode.env | Adds Xcode env script for RN build phases. |
| example-bare/index.js | Adds RN entrypoint for bare RN example. |
| example-bare/Gemfile.lock | Adds Ruby deps lockfile for bare RN example iOS tooling. |
| example-bare/Gemfile | Adds Ruby deps for CocoaPods/tooling in bare RN example. |
| example-bare/env.local.example.ts | Adds local env template (secrets) for the bare RN example. |
| example-bare/createDemoSession.ts | Adds helper to create demo sessions for the example app. |
| example-bare/babel.config.js | Adds Babel config for bare RN example. |
| example-bare/App.tsx | Adds full bare RN demo app exercising the new Nitro-based API. |
| example-bare/app.json | Adds RN app metadata for bare RN example. |
| example-bare/android/settings.gradle | Adds Android settings for bare RN example. |
| example-bare/android/gradlew.bat | Adds Gradle wrapper script (Windows). |
| example-bare/android/gradlew | Adds Gradle wrapper script (POSIX). |
| example-bare/android/gradle/wrapper/gradle-wrapper.properties | Adds Gradle wrapper version/pinning. |
| example-bare/android/gradle.properties | Adds Android build flags (incl new arch, Hermes). |
| example-bare/android/build.gradle | Adds Android root build configuration for example. |
| example-bare/android/app/src/main/res/values/styles.xml | Adds Android styles for example. |
| example-bare/android/app/src/main/res/values/strings.xml | Adds Android strings for example. |
| example-bare/android/app/src/main/res/drawable/rn_edit_text_material.xml | Adds Android drawable for RN EditText background. |
| example-bare/android/app/src/main/java/com/onramperbare/MainApplication.kt | Adds Android application class for example. |
| example-bare/android/app/src/main/java/com/onramperbare/MainActivity.kt | Adds Android activity class for example. |
| example-bare/android/app/src/main/AndroidManifest.xml | Adds Android manifest for example. |
| example-bare/android/app/proguard-rules.pro | Adds Proguard rules placeholder for example. |
| example-bare/android/app/build.gradle | Adds Android app build configuration for example. |
| example-bare/.watchmanconfig | Adds Watchman config for example. |
| example-bare/.prettierrc.js | Adds Prettier config for example. |
| example-bare/.gitignore | Adds ignore rules for example. |
| example-bare/.eslintrc.js | Adds ESLint config for example. |
| example-bare/.bundle/config | Adds Bundler config for example. |
| example-bare/tests/App.test.tsx | Adds a basic render test for the bare RN example. |
| app.plugin.js | Adds Expo config plugin to apply iOS deployment target + Swift modules workaround. |
| .gitignore | Ignores bare example local secrets file. |
| tests/OnramperClient.test.ts | Updates unit tests for Nitro-based native mocking and per-client listeners. |
| tests/mocks/react-native-nitro-modules.ts | Adds Nitro module mock for Jest. |
| tests/mocks/expo-modules-core.ts | Removes Expo modules mock (no longer used). |
Files not reviewed (2)
- example-bare/ios/OnramperBare.xcworkspace/contents.xcworkspacedata: Language not supported
- example/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…eployment target The SDK's real minimum is iOS 16.0 (onramper-sdk Package.swift declares .iOS(.v16); no @available(iOS 16.4) anywhere) — the 16.4 in the podspec + plugin was an arbitrary number carried over from the Expo-era example config. - podspec: s.platforms ios 16.4 -> 16.0 (the package's true floor). - app.plugin.js: drop the deployment-target override — raising a consumer's app-wide minimum iOS is their product decision, not ours. Keep only the SWIFT_ENABLE_EXPLICIT_MODULES=NO build-correctness fix. - docs: package floor is 16.0 (bare RN); note that Expo SDK 56 apps require 16.4 (Expo's own minimum — surfaced when the example built: expo-modules-core et al. 'require iOS 16.4'), which is why the Expo example targets 16.4. Verified: Expo example BUILD SUCCEEDED at 16.4; podspec floor 16.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Complete the Expo->Nitro migration on the packaging side. A Nitro module needs no Expo build tooling, and expo-module-scripts' `prepare` step was rewriting tsconfig.json on every install (stripping resolveJsonModule and the nitrogen json include), which broke `tsc` / `npm ci` locally and in CI. - swap JS/TS build to react-native-builder-bob (commonjs+module+typescript); update main/module/types/exports/files for the lib/ layout - self-contained tsconfig.json (no expo-module-scripts base) — permanently ends the tsconfig clobber - vendor the nitrogen-generated Fabric view config into src/generated via scripts/sync-view-config.js (wired into `npm run nitrogen`) so bob's lib/ output resolves the import correctly; nitrogen stays the source of truth - drop the unused react-test-renderer devDep and the --legacy-peer-deps flag from ci.yml/release.yml (peer resolution is now clean) - remove the vestigial universe-based .eslintrc.js (lint uses biome) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n re-hosting Addresses the PR #1 Copilot review feedback on the checkout flow. - HybridOnramperNitro: replace the process-wide PreparedIntentRegistry.invalidateAll() with a per-instance lastPreparedHandle. getCheckoutRequirements now drops only this client's prior unconsumed handle before storing the new one (cleared in cancelPreparedIntent and dispose), so one client no longer invalidates other clients' checkout buttons. - HybridOnramperCheckoutButton: host() now tears down the previously hosted UIHostingController via detachHosted() before installing the new one, so re-assigning intentHandle no longer accumulates subviews/constraints or leaves the old controller childed to the parent VC. - Tests: cover getCheckoutRequirements (JSON request/style serialization, quote parsing, button element, buttonStyle default, native error wrapping) and cancelPreparedIntent forwarding; add both methods to the Nitro mock. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…od path - example-bare: declare the App Attest entitlement (com.apple.developer.devicecheck.appattest-environment = development) so on-device checkout works with the SDK, matching the Expo example. - example Podfile.lock: correct the NitroModules pod path from ../../node_modules to ../node_modules and refresh the OnramperReactNative checksum. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The auto GITHUB_TOKEN is scoped to this repo only and can't read the private onramper/onramper-ios release. Pass a fine-grained PAT via GH_TOKEN so `gh release download` can authenticate cross-repo. Remove once onramper-ios is public. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…o app to example-expo Since the Nitro migration the bare React Native app is the canonical example, so make the directory layout reflect that: - example (Expo) -> example-expo - example-bare (bare) -> example Rebrand the bare app's identity OnramperBare -> OnramperExample across package.json, app.json, Android rootProject.name / app_name, getMainComponentName, iOS moduleName, and the iOS target / scheme / project / workspace / Podfile target. Android applicationId (com.onramperbare) and iOS bundle id (com.onramper.demo.react-native) are intentionally unchanged so signing/install identity stays stable. Disambiguate the Expo app's package name to onramper-react-native-example-expo, and replace its stock RN-CLI README with Expo-specific launch steps (prebuild + dev client, env.local.ts, xcframework fetch). Update root references: .gitignore example/* -> example-expo/* (Expo artifacts) and example-bare/env.local.ts -> example/env.local.ts; tsconfig exclude example-bare -> example-expo. Both apps verified building: example (xcodebuild) and example-expo (expo run:ios) build and launch on simulator.
Validated that @onramper/react-native builds, bundles, and renders on a physical device at RN 0.79.7 + React 19 (the lowest RN that ships React 19). The library uses no React-19-only or 0.85-only APIs, and the generated Nitro view degrades gracefully below RN 0.82. Update README and INTEGRATION docs to match (RN 0.79+; New Architecture is default on RN 0.76+).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This allow us to serve RN without Expo