framepayments-react-native 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,44 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'FrameReactNative'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.homepage = package['homepage']
10
+ s.license = package['license']
11
+ s.authors = package['author']
12
+ s.platforms = { :ios => '17.0' }
13
+ s.source = { :git => package['repository']['url'], :tag => "#{s.version}" }
14
+ s.source_files = 'ios/**/*.{h,m,mm,swift}'
15
+ s.requires_arc = true
16
+
17
+ # static_framework exposes the pod's generated `FrameReactNative-Swift.h` to
18
+ # consumers — required so host AppDelegate.mm can `#import <FrameReactNative/FrameReactNative-Swift.h>`
19
+ # to reach `FramePreloader`.
20
+ s.static_framework = true
21
+
22
+ s.dependency 'React-Core'
23
+
24
+ # Autolink Frame-iOS (SPM-only) via RN 0.81+'s Podfile SPM hook. spm.rb injects
25
+ # XCRemoteSwiftPackageReferences into Pods.xcodeproj at react_native_post_install;
26
+ # consumers get Frame-iOS + Frame-Onboarding resolved by `pod install` alone.
27
+ #
28
+ # The respond_to? guards use `include_private: true` because both helpers are
29
+ # top-level Ruby `def`s in react_native_pods.rb — i.e. private methods of Object.
30
+ # The guards exist not for RN-version compatibility (peer dep is >= 0.81) but
31
+ # because the RN CLI loads this podspec STANDALONE for autolinking discovery,
32
+ # outside the Podfile's `require 'react_native_pods.rb'` context where the
33
+ # helpers are defined. Without guards, `npx react-native config` would crash
34
+ # and return `ios: null`, breaking `use_native_modules!`.
35
+ if respond_to?(:spm_dependency, true)
36
+ spm_dependency(s,
37
+ url: 'https://github.com/Frame-Payments/frame-ios',
38
+ requirement: { kind: 'upToNextMajorVersion', minimumVersion: package['frameNativeVersions']['ios'] },
39
+ products: ['Frame-iOS', 'Frame-Onboarding']
40
+ )
41
+ end
42
+
43
+ install_modules_dependencies(s) if respond_to?(:install_modules_dependencies, true)
44
+ end
package/Package.swift ADDED
@@ -0,0 +1,47 @@
1
+ // swift-tools-version: 5.9
2
+ // Distribution paths:
3
+ // • Pure-SPM consumers: add framepayments-react-native via Swift Package Manager;
4
+ // frame-ios resolves transitively from this manifest.
5
+ // • CocoaPods consumers (the common RN setup): the podspec at
6
+ // ios/FrameReactNative.podspec declares the same frame-ios SPM dependency via
7
+ // RN 0.81+'s `spm_dependency` Podfile hook, so `pod install` resolves it
8
+ // automatically — no Xcode "Add Package Dependencies" step required.
9
+ //
10
+ // IMPORTANT: keep the frame-ios version below in sync with
11
+ // package.json:frameNativeVersions.ios. Swift Package manifests cannot read JSON,
12
+ // so this is the one duplicated version pin. See MAINTAINING.md.
13
+
14
+ import PackageDescription
15
+
16
+ let package = Package(
17
+ name: "framepayments-react-native",
18
+ platforms: [
19
+ .iOS(.v17)
20
+ ],
21
+ products: [
22
+ .library(
23
+ name: "framepayments-react-native",
24
+ targets: ["framepayments-react-native"]
25
+ )
26
+ ],
27
+ dependencies: [
28
+ .package(
29
+ url: "https://github.com/Frame-Payments/frame-ios",
30
+ from: "2.2.2" // Keep in sync with package.json:frameNativeVersions.ios
31
+ )
32
+ ],
33
+ targets: [
34
+ .target(
35
+ name: "framepayments-react-native",
36
+ dependencies: [
37
+ .product(name: "Frame-iOS", package: "frame-ios"),
38
+ .product(name: "Frame-Onboarding", package: "frame-ios")
39
+ ],
40
+ path: "ios",
41
+ publicHeadersPath: ".",
42
+ cSettings: [
43
+ .headerSearchPath(".")
44
+ ]
45
+ )
46
+ ]
47
+ )
package/README.md CHANGED
@@ -4,7 +4,7 @@ React Native SDK for [Frame Payments](https://framepayments.com). Bridges the na
4
4
 
5
5
  ## Requirements
6
6
 
7
- - React Native >= 0.74
7
+ - React Native >= 0.81 (autolinking on iOS depends on RN's `spm_dependency` Podfile hook, which stabilized in 0.81)
8
8
  - iOS 17+ / Android 8.0+ (API 26+)
9
9
  - A [Frame](https://framepayments.com) account and API key
10
10
 
@@ -18,19 +18,13 @@ yarn add framepayments-react-native
18
18
 
19
19
  ### iOS setup
20
20
 
21
- #### 1. Add the Frame iOS SDK via Swift Package Manager
22
-
23
- The React Native SDK's native layer depends on the Frame iOS SDK, which must be added manually via SPM — CocoaPods cannot pull it in automatically.
24
-
25
- In Xcode: **File → Add Package Dependencies**, enter:
26
-
27
- ```
28
- https://github.com/Frame-Payments/frame-ios
21
+ ```bash
22
+ cd ios && pod install && cd ..
29
23
  ```
30
24
 
31
- Add the **Frame-iOS** package and select the version you need.
25
+ That's it. `pod install` autolinks the React Native bridge **and** resolves the underlying Frame iOS SDK (Frame-iOS + Frame-Onboarding) via Swift Package Manager — no Xcode "Add Package Dependencies" step required.
32
26
 
33
- #### 2. Preload Frame on the main thread
27
+ #### Preload Frame on the main thread
34
28
 
35
29
  Add this to your `AppDelegate.m` or `AppDelegate.mm` **before** `[super application:didFinishLaunchingWithOptions:]`:
36
30
 
@@ -48,15 +42,11 @@ This prevents the **"Helpers are not supported by the default hub"** crash, whic
48
42
 
49
43
  > If your app module name isn't the default (i.e., not matching the generated `-Swift.h` header), set `FRAME_SWIFT_HEADER=YourApp-Swift.h` in your target's **Preprocessor Macros** in Xcode build settings.
50
44
 
51
- #### 3. Install pods
52
-
53
- ```bash
54
- cd ios && pod install && cd ..
55
- ```
45
+ > Using Swift Package Manager directly instead of CocoaPods? The package's `Package.swift` resolves `frame-ios` transitively, so just add `framepayments-react-native` via **File → Add Package Dependencies** in Xcode.
56
46
 
57
47
  ### Android setup
58
48
 
59
- No extra steps required. Autolinking handles the native module automatically.
49
+ No extra steps required. Autolinking handles the native module automatically and pulls in `com.framepayments:framesdk*` from Maven Central.
60
50
 
61
51
  ---
62
52
 
@@ -1,3 +1,5 @@
1
+ import groovy.json.JsonSlurper
2
+
1
3
  apply plugin: 'com.android.library'
2
4
  apply plugin: 'kotlin-android'
3
5
  apply plugin: 'org.jetbrains.kotlin.plugin.compose'
@@ -6,6 +8,10 @@ def safeExtGet(prop, fallback) {
6
8
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
7
9
  }
8
10
 
11
+ // Single source of truth for Frame native SDK versions — see package.json:frameNativeVersions.
12
+ def frameNativeVersions = new JsonSlurper().parse(file("$projectDir/../package.json")).frameNativeVersions
13
+ def frameAndroidVersion = frameNativeVersions.android
14
+
9
15
  android {
10
16
  namespace "com.framepayments.reactnativeframe"
11
17
  compileSdk safeExtGet('compileSdkVersion', 36)
@@ -31,9 +37,9 @@ android {
31
37
  dependencies {
32
38
  implementation 'com.facebook.react:react-native:+'
33
39
  implementation "org.jetbrains.kotlin:kotlin-stdlib:2.1.0"
34
- implementation 'com.framepayments:framesdk:2.0.7'
35
- implementation 'com.framepayments:framesdk_ui:2.0.7'
36
- implementation 'com.framepayments:framesdk_onboarding:2.0.7'
40
+ implementation "com.framepayments:framesdk:${frameAndroidVersion}"
41
+ implementation "com.framepayments:framesdk_ui:${frameAndroidVersion}"
42
+ implementation "com.framepayments:framesdk_onboarding:${frameAndroidVersion}"
37
43
  // Required by FrameGooglePayButton (PaymentsClient, WalletConstants).
38
44
  // framesdk_ui declares this as `implementation`, so it is not exposed transitively.
39
45
  implementation 'com.google.android.gms:play-services-wallet:19.4.0'
@@ -7,9 +7,10 @@ import com.facebook.react.bridge.Promise
7
7
  import com.facebook.react.bridge.ReactApplicationContext
8
8
  import com.facebook.react.bridge.ReactContextBaseJavaModule
9
9
  import com.facebook.react.bridge.ReactMethod
10
+ import com.facebook.react.bridge.ReadableArray
11
+ import com.facebook.react.bridge.ReadableMap
10
12
  import com.facebook.react.bridge.WritableNativeMap
11
13
  import com.framepayments.framesdk.FrameNetworking
12
- import org.json.JSONObject
13
14
 
14
15
  class FrameSDKModule(reactContext: ReactApplicationContext) :
15
16
  ReactContextBaseJavaModule(reactContext), ActivityEventListener {
@@ -35,7 +36,7 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
35
36
  secretKey: String,
36
37
  publishableKey: String,
37
38
  debugMode: Boolean,
38
- theme: com.facebook.react.bridge.ReadableMap?,
39
+ theme: ReadableMap?,
39
40
  promise: Promise
40
41
  ) {
41
42
  try {
@@ -69,7 +70,7 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
69
70
  @ReactMethod
70
71
  fun presentCart(
71
72
  accountId: String?,
72
- items: com.facebook.react.bridge.ReadableArray,
73
+ items: ReadableArray,
73
74
  shippingAmountInCents: Double,
74
75
  promise: Promise
75
76
  ) {
@@ -137,7 +138,7 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
137
138
  @ReactMethod
138
139
  fun presentOnboarding(
139
140
  accountId: String?,
140
- capabilities: com.facebook.react.bridge.ReadableArray,
141
+ capabilities: ReadableArray,
141
142
  googlePayMerchantId: String?,
142
143
  promise: Promise
143
144
  ) {
@@ -157,7 +158,7 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
157
158
  }
158
159
  }
159
160
 
160
- private fun readableArrayToJson(items: com.facebook.react.bridge.ReadableArray): String? {
161
+ private fun readableArrayToJson(items: ReadableArray): String? {
161
162
  val arr = org.json.JSONArray()
162
163
  for (i in 0 until items.size()) {
163
164
  val item = items.getMap(i) ?: return null
@@ -171,7 +172,7 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
171
172
  return arr.toString()
172
173
  }
173
174
 
174
- private fun readableArrayToJsonArray(arr: com.facebook.react.bridge.ReadableArray): String {
175
+ private fun readableArrayToJsonArray(arr: ReadableArray): String {
175
176
  val jsonArr = org.json.JSONArray()
176
177
  for (i in 0 until arr.size()) {
177
178
  arr.getString(i)?.let { jsonArr.put(it) }
@@ -0,0 +1,23 @@
1
+ //
2
+ // FramePreloader.h
3
+ // FrameReactNative
4
+ //
5
+ // Public Obj-C interface for the Swift `FramePreloader` class. Lets consumers
6
+ // reach `+[FramePreloader preloadOnMainThread]` from AppDelegate.mm (or any
7
+ // .m/.mm file) via `#import "FramePreloader.h"`, without needing modules
8
+ // enabled in C++ context.
9
+ //
10
+
11
+ #import <Foundation/Foundation.h>
12
+
13
+ NS_ASSUME_NONNULL_BEGIN
14
+
15
+ @interface FramePreloader : NSObject
16
+
17
+ /// Call from AppDelegate before [super application:didFinishLaunchingWithOptions:].
18
+ /// Forces Frame (and its deps: Evervault, Sift) to load on the main thread.
19
+ + (void)preloadOnMainThread;
20
+
21
+ @end
22
+
23
+ NS_ASSUME_NONNULL_END
@@ -8,16 +8,16 @@
8
8
  #import <React/RCTBridgeModule.h>
9
9
  #import "FrameVCHelper.h"
10
10
 
11
- // Import app's Swift header (ObjCFrameSDKBridge, FramePreloader). The example uses FrameExampleTemp.
12
- // If your app has a different module name, add Preprocessor Macro: FRAME_SWIFT_HEADER="YourApp-Swift.h"
13
- #if defined(FRAME_SWIFT_HEADER)
14
- #import FRAME_SWIFT_HEADER
15
- #elif __has_include("FrameExampleTemp-Swift.h")
16
- #import "FrameExampleTemp-Swift.h"
17
- #elif __has_include(<FrameExampleTemp/FrameExampleTemp-Swift.h>)
18
- #import <FrameExampleTemp/FrameExampleTemp-Swift.h>
11
+ // Import the FrameReactNative pod's auto-generated Swift header so this Obj-C
12
+ // file can reach the Swift `ObjCFrameSDKBridge` class. CocoaPods generates
13
+ // "FrameReactNative-Swift.h" from the pod's Swift sources during the pod's
14
+ // build phase.
15
+ #if __has_include("FrameReactNative-Swift.h")
16
+ #import "FrameReactNative-Swift.h"
17
+ #elif __has_include(<FrameReactNative/FrameReactNative-Swift.h>)
18
+ #import <FrameReactNative/FrameReactNative-Swift.h>
19
19
  #else
20
- #error "Swift header not found. Add FRAME_SWIFT_HEADER=\"YourApp-Swift.h\" to your app target's Preprocessor Macros, or ensure Swift files compile before this file."
20
+ #error "FrameReactNative-Swift.h not found. The Frame React Native pod's Swift code did not generate its module header check that pod install ran cleanly."
21
21
  #endif
22
22
 
23
23
  @interface FrameSDKModule : NSObject <RCTBridgeModule>
@@ -106,33 +106,30 @@ public class FrameSDKBridge: NSObject {
106
106
  // MARK: - Private helpers
107
107
 
108
108
  private func presentCheckoutOnMain(from top: UIViewController, accountId: String, amount: Int, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
109
- var hosting: CheckoutHostingController!
110
- hosting = CheckoutHostingController(rootView: FrameCheckoutView(
109
+ // Single dismiss delegate guards against double-resolve: the inner checkout
110
+ // calls `finish(.success)` with the transfer id; bare-dismiss (swipe-down
111
+ // without completing checkout) calls `finish(.cancel)`.
112
+ let delegate = CheckoutDismissDelegate(resolve: resolve, reject: reject)
113
+ let checkoutView = FrameCheckoutView(
111
114
  accountId: accountId,
112
115
  paymentAmount: amount,
113
- checkoutCallback: { [weak hosting] success, transferId in
114
- hosting?.didComplete = true
115
- top.dismiss(animated: true)
116
- DispatchQueue.main.async {
117
- if success, let transferId {
118
- resolve(transferId)
119
- } else {
120
- reject("PAYMENT_FAILED", "Checkout did not produce a transfer id", nil)
121
- }
116
+ checkoutCallback: { [weak top, delegate] success, transferId in
117
+ if success, let transferId {
118
+ delegate.finish(.success(transferId))
119
+ } else {
120
+ delegate.finish(.failure)
122
121
  }
122
+ top?.dismiss(animated: true)
123
123
  }
124
- ))
125
- hosting.onCancel = {
126
- DispatchQueue.main.async {
127
- reject("USER_CANCELED", "User dismissed checkout without completing payment", nil)
128
- }
129
- }
124
+ )
125
+ let hosting = UIHostingController(rootView: checkoutView)
130
126
  hosting.modalPresentationStyle = UIModalPresentationStyle.pageSheet
131
127
  if let sheet = hosting.sheetPresentationController {
132
128
  sheet.detents = [UISheetPresentationController.Detent.large()]
133
129
  }
130
+ objc_setAssociatedObject(hosting, &checkoutDismissKey, delegate, .OBJC_ASSOCIATION_RETAIN)
134
131
  top.present(hosting, animated: true) {
135
- hosting.presentationController?.delegate = hosting
132
+ hosting.presentationController?.delegate = delegate
136
133
  }
137
134
  }
138
135
 
@@ -237,30 +234,44 @@ public class FrameSDKBridge: NSObject {
237
234
  }
238
235
  }
239
236
 
240
- // MARK: - CheckoutHostingController
237
+ // MARK: - OnboardingHostingController
241
238
 
242
- private final class CheckoutHostingController: UIHostingController<FrameCheckoutView>, UIAdaptivePresentationControllerDelegate {
243
- var didComplete = false
244
- var onCancel: (() -> Void)?
245
- private var cancelled = false
239
+ private final class OnboardingHostingController<V: View>: UIHostingController<V> {}
246
240
 
247
- func cancel() {
248
- guard !didComplete, !cancelled else { return }
249
- cancelled = true
250
- onCancel?()
251
- }
241
+ // MARK: - Delegates
252
242
 
253
- func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
254
- guard presentationController.presentedViewController === self else { return }
255
- cancel()
243
+ private final class CheckoutDismissDelegate: NSObject, UIAdaptivePresentationControllerDelegate {
244
+ enum Outcome {
245
+ case success(String)
246
+ case failure
247
+ case cancel
256
248
  }
257
- }
258
249
 
259
- // MARK: - OnboardingHostingController
250
+ private let resolve: RCTPromiseResolveBlock
251
+ private let reject: RCTPromiseRejectBlock
252
+ private var didFinish = false
260
253
 
261
- private final class OnboardingHostingController<V: View>: UIHostingController<V> {}
254
+ init(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
255
+ self.resolve = resolve
256
+ self.reject = reject
257
+ }
262
258
 
263
- // MARK: - Delegates
259
+ func finish(_ outcome: Outcome) {
260
+ guard !didFinish else { return }
261
+ didFinish = true
262
+ DispatchQueue.main.async { [resolve, reject] in
263
+ switch outcome {
264
+ case .success(let transferId): resolve(transferId)
265
+ case .failure: reject("PAYMENT_FAILED", "Checkout did not produce a transfer id", nil)
266
+ case .cancel: reject("USER_CANCELED", "User dismissed checkout without completing payment", nil)
267
+ }
268
+ }
269
+ }
270
+
271
+ func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
272
+ finish(.cancel)
273
+ }
274
+ }
264
275
 
265
276
  private final class CartDismissDelegate: NSObject, UIAdaptivePresentationControllerDelegate {
266
277
  enum Outcome {
@@ -319,5 +330,6 @@ private final class OnboardingDismissDelegate: NSObject, UIAdaptivePresentationC
319
330
  }
320
331
  }
321
332
 
333
+ private var checkoutDismissKey: UInt8 = 0
322
334
  private var cartDismissKey: UInt8 = 0
323
335
  private var onboardingDismissKey: UInt8 = 0
@@ -1 +1 @@
1
- {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAiCjB,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBhB;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;CAC/B,GAAG,OAAO,CAAC,MAAM,CAAC,CAYlB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACtC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkB5B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBhF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBlF"}
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAiCjB,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBhB;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;CAC/B,GAAG,OAAO,CAAC,MAAM,CAAC,CAYlB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACtC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkB5B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBhF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlF"}
package/lib/native.js CHANGED
@@ -3,6 +3,14 @@
3
3
  */
4
4
  import { NativeModules, Platform } from 'react-native';
5
5
  import { ErrorCodes } from './errors';
6
+ const LINKING_ERROR = `The package 'framepayments-react-native' doesn't seem to be linked. Make sure you have run 'pod install' (iOS) or rebuilt the app (Android).`;
7
+ const FrameSDK = NativeModules.FrameSDK
8
+ ? NativeModules.FrameSDK
9
+ : new Proxy({}, {
10
+ get() {
11
+ throw new Error(LINKING_ERROR);
12
+ },
13
+ });
6
14
  /**
7
15
  * Throw a coded error from synchronous JS validation. Mirrors the `code`/`message`
8
16
  * shape that native rejections produce so consumers can catch `e.code === 'INVALID_*'`
@@ -15,14 +23,6 @@ function throwCoded(code, message) {
15
23
  }
16
24
  // theme is iOS-only today: frame-android does not yet have a matching theme API,
17
25
  // so the field is accepted on both platforms but ignored on Android until it does.
18
- const LINKING_ERROR = `The package 'framepayments-react-native' doesn't seem to be linked. Make sure you have run 'pod install' (iOS) or rebuilt the app (Android).`;
19
- const FrameSDK = NativeModules.FrameSDK
20
- ? NativeModules.FrameSDK
21
- : new Proxy({}, {
22
- get() {
23
- throw new Error(LINKING_ERROR);
24
- },
25
- });
26
26
  let isInitialized = false;
27
27
  export function initialize(options) {
28
28
  if (!options?.secretKey) {
@@ -104,6 +104,9 @@ export function presentOnboarding(options) {
104
104
  */
105
105
  export function presentApplePay(options) {
106
106
  guardInitialized();
107
+ if (Platform.OS !== 'ios') {
108
+ throwCoded('PLATFORM_UNSUPPORTED', 'Frame.presentApplePay is iOS-only; use presentGooglePay on Android.');
109
+ }
107
110
  if (!options?.owner || (options.owner.type !== 'customer' && options.owner.type !== 'account')) {
108
111
  throwCoded(ErrorCodes.INVALID_OWNER, 'Frame.presentApplePay requires owner: { type: "customer" | "account", id: string }');
109
112
  }
@@ -124,6 +127,9 @@ export function presentApplePay(options) {
124
127
  */
125
128
  export function presentGooglePay(options) {
126
129
  guardInitialized();
130
+ if (Platform.OS !== 'android') {
131
+ throwCoded('PLATFORM_UNSUPPORTED', 'Frame.presentGooglePay is Android-only; use presentApplePay on iOS.');
132
+ }
127
133
  if (!options?.owner || (options.owner.type !== 'customer' && options.owner.type !== 'account')) {
128
134
  throwCoded(ErrorCodes.INVALID_OWNER, 'Frame.presentGooglePay requires owner: { type: "customer" | "account", id: string }');
129
135
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framepayments-react-native",
3
- "version": "2.2.0",
3
+ "version": "3.0.0",
4
4
  "description": "React Native SDK for Frame Payments - modal checkout and cart, with API usage via frame-node.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -31,7 +31,11 @@
31
31
  "homepage": "https://github.com/Frame-Payments/frame-react-native#readme",
32
32
  "peerDependencies": {
33
33
  "react": "*",
34
- "react-native": ">=0.74.0"
34
+ "react-native": ">=0.81.0"
35
+ },
36
+ "frameNativeVersions": {
37
+ "ios": "2.2.2",
38
+ "android": "2.0.8"
35
39
  },
36
40
  "devDependencies": {
37
41
  "@types/jest": "^29.5.0",
@@ -54,6 +58,8 @@
54
58
  "lib",
55
59
  "ios",
56
60
  "android",
61
+ "FrameReactNative.podspec",
62
+ "Package.swift",
57
63
  "README.md",
58
64
  "LICENSE"
59
65
  ],
@@ -224,6 +224,11 @@ describe('presentApplePay', () => {
224
224
  });
225
225
 
226
226
  describe('presentGooglePay', () => {
227
+ beforeEach(() => {
228
+ // presentGooglePay is Android-only; tests run on Android except where noted.
229
+ mockPlatform.OS = 'android';
230
+ });
231
+
227
232
  it('throws NOT_INITIALIZED if initialize was not called', async () => {
228
233
  try {
229
234
  await presentGooglePay({ amountCents: 100, owner: { type: 'account', id: 'acct_1' } });
package/src/native.ts CHANGED
@@ -13,20 +13,6 @@ import type {
13
13
  } from './types';
14
14
  import { ErrorCodes } from './errors';
15
15
 
16
- /**
17
- * Throw a coded error from synchronous JS validation. Mirrors the `code`/`message`
18
- * shape that native rejections produce so consumers can catch `e.code === 'INVALID_*'`
19
- * uniformly.
20
- */
21
- function throwCoded(code: string, message: string): never {
22
- const err = new Error(message) as Error & { code: string };
23
- err.code = code;
24
- throw err;
25
- }
26
-
27
- // theme is iOS-only today: frame-android does not yet have a matching theme API,
28
- // so the field is accepted on both platforms but ignored on Android until it does.
29
-
30
16
  const LINKING_ERROR =
31
17
  `The package 'framepayments-react-native' doesn't seem to be linked. Make sure you have run 'pod install' (iOS) or rebuilt the app (Android).`;
32
18
 
@@ -41,6 +27,20 @@ const FrameSDK = NativeModules.FrameSDK
41
27
  }
42
28
  );
43
29
 
30
+ /**
31
+ * Throw a coded error from synchronous JS validation. Mirrors the `code`/`message`
32
+ * shape that native rejections produce so consumers can catch `e.code === 'INVALID_*'`
33
+ * uniformly.
34
+ */
35
+ function throwCoded(code: string, message: string): never {
36
+ const err = new Error(message) as Error & { code: string };
37
+ err.code = code;
38
+ throw err;
39
+ }
40
+
41
+ // theme is iOS-only today: frame-android does not yet have a matching theme API,
42
+ // so the field is accepted on both platforms but ignored on Android until it does.
43
+
44
44
  let isInitialized = false;
45
45
 
46
46
  export function initialize(options: {
@@ -179,6 +179,9 @@ export function presentOnboarding(options: {
179
179
  */
180
180
  export function presentApplePay(options: PresentApplePayOptions): Promise<string> {
181
181
  guardInitialized();
182
+ if (Platform.OS !== 'ios') {
183
+ throwCoded('PLATFORM_UNSUPPORTED', 'Frame.presentApplePay is iOS-only; use presentGooglePay on Android.');
184
+ }
182
185
  if (!options?.owner || (options.owner.type !== 'customer' && options.owner.type !== 'account')) {
183
186
  throwCoded(ErrorCodes.INVALID_OWNER, 'Frame.presentApplePay requires owner: { type: "customer" | "account", id: string }');
184
187
  }
@@ -208,6 +211,9 @@ export function presentApplePay(options: PresentApplePayOptions): Promise<string
208
211
  */
209
212
  export function presentGooglePay(options: PresentGooglePayOptions): Promise<string> {
210
213
  guardInitialized();
214
+ if (Platform.OS !== 'android') {
215
+ throwCoded('PLATFORM_UNSUPPORTED', 'Frame.presentGooglePay is Android-only; use presentApplePay on iOS.');
216
+ }
211
217
  if (!options?.owner || (options.owner.type !== 'customer' && options.owner.type !== 'account')) {
212
218
  throwCoded(ErrorCodes.INVALID_OWNER, 'Frame.presentGooglePay requires owner: { type: "customer" | "account", id: string }');
213
219
  }
@@ -1,32 +0,0 @@
1
- require 'json'
2
-
3
- package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
4
-
5
- Pod::Spec.new do |s|
6
- s.name = 'FrameReactNative'
7
- s.version = package['version']
8
- s.summary = package['description']
9
- s.homepage = package['homepage']
10
- s.license = package['license']
11
- s.authors = package['author']
12
- s.platforms = { :ios => '17.0' }
13
- s.source = { :git => package['repository']['url'], :tag => "#{s.version}" }
14
- s.source_files = '**/*.{h,m,mm,swift}'
15
- s.requires_arc = true
16
-
17
- s.dependency 'React-Core'
18
-
19
- # Frame-iOS SDK (Frame + FrameOnboarding) must be available to the app.
20
- #
21
- # SPM users (RN >= 0.73): add framepayments-react-native via Swift Package Manager.
22
- # Frame and FrameOnboarding are declared as dependencies in Package.swift and resolve
23
- # automatically — no manual step required.
24
- #
25
- # CocoaPods users: add frame-ios manually via Xcode:
26
- # File → Add Package Dependencies → https://github.com/Frame-Payments/frame-ios
27
- # Add both the "Frame-iOS" and "Frame-Onboarding" products to your app target.
28
- # If Frame-iOS is published as a pod in the future, replace the above with:
29
- # s.dependency 'Frame-iOS'
30
-
31
- install_modules_dependencies(s) if respond_to?(:install_modules_dependencies)
32
- end
@@ -1,32 +0,0 @@
1
- /**
2
- * Unit tests for the native module bridge (initialize, presentCheckout, presentCart).
3
- * NativeModules.FrameSDK is mocked.
4
- */
5
- declare const mockInitialize: jest.Mock<Promise<void>, [_apiKey: string, _debugMode: boolean], any>;
6
- declare const mockPresentCheckout: jest.Mock<Promise<{
7
- id: string;
8
- amount: number;
9
- }>, [_customerId: unknown, _amount: number], any>;
10
- declare const mockPresentCart: jest.Mock<Promise<{
11
- id: string;
12
- amount: number;
13
- }>, [_customerId: unknown, _items: unknown[], _shipping: number], any>;
14
- declare let initialize: (opts: {
15
- apiKey: string;
16
- debugMode?: boolean;
17
- }) => void;
18
- declare let presentCheckout: (opts: {
19
- customerId?: string | null;
20
- amount: number;
21
- }) => Promise<unknown>;
22
- declare let presentCart: (opts: {
23
- customerId?: string | null;
24
- items: Array<{
25
- id: string;
26
- title: string;
27
- amountInCents: number;
28
- imageUrl: string;
29
- }>;
30
- shippingAmountInCents: number;
31
- }) => Promise<unknown>;
32
- //# sourceMappingURL=native.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"native.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/native.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,QAAA,MAAM,cAAc,uEAAuE,CAAC;AAC5F,QAAA,MAAM,mBAAmB;;;iDAAqG,CAAC;AAC/H,QAAA,MAAM,eAAe;;;sEAA0H,CAAC;AAahJ,QAAA,IAAI,UAAU,EAAE,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,KAAK,IAAI,CAAC;AACxE,QAAA,IAAI,eAAe,EAAE,CAAC,IAAI,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAChG,QAAA,IAAI,WAAW,EAAE,CAAC,IAAI,EAAE;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrF,qBAAqB,EAAE,MAAM,CAAC;CAC/B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC"}
@@ -1,101 +0,0 @@
1
- "use strict";
2
- /**
3
- * Unit tests for the native module bridge (initialize, presentCheckout, presentCart).
4
- * NativeModules.FrameSDK is mocked.
5
- */
6
- const mockInitialize = jest.fn((_apiKey, _debugMode) => Promise.resolve());
7
- const mockPresentCheckout = jest.fn((_customerId, _amount) => Promise.resolve({ id: 'ci_1', amount: 10000 }));
8
- const mockPresentCart = jest.fn((_customerId, _items, _shipping) => Promise.resolve({ id: 'ci_2', amount: 15000 }));
9
- jest.mock('react-native', () => ({
10
- NativeModules: {
11
- FrameSDK: {
12
- initialize: mockInitialize,
13
- presentCheckout: mockPresentCheckout,
14
- presentCart: mockPresentCart,
15
- },
16
- },
17
- }));
18
- // Re-import after mock so we get the mocked NativeModules
19
- let initialize;
20
- let presentCheckout;
21
- let presentCart;
22
- beforeEach(() => {
23
- jest.resetModules();
24
- mockInitialize.mockClear();
25
- mockPresentCheckout.mockClear();
26
- mockPresentCart.mockClear();
27
- const native = require('../native');
28
- initialize = native.initialize;
29
- presentCheckout = native.presentCheckout;
30
- presentCart = native.presentCart;
31
- });
32
- describe('initialize', () => {
33
- it('calls native FrameSDK.initialize with apiKey and debugMode', () => {
34
- initialize({ apiKey: 'sk_test_xxx', debugMode: true });
35
- expect(mockInitialize).toHaveBeenCalledTimes(1);
36
- expect(mockInitialize).toHaveBeenCalledWith('sk_test_xxx', true);
37
- });
38
- it('defaults debugMode to false', () => {
39
- initialize({ apiKey: 'sk_test_yyy' });
40
- expect(mockInitialize).toHaveBeenCalledWith('sk_test_yyy', false);
41
- });
42
- it('throws if apiKey is missing', () => {
43
- expect(() => initialize({ apiKey: '' })).toThrow();
44
- expect(() => initialize({})).toThrow();
45
- expect(mockInitialize).not.toHaveBeenCalled();
46
- });
47
- });
48
- describe('presentCheckout', () => {
49
- it('throws NOT_INITIALIZED if initialize was not called', async () => {
50
- try {
51
- await presentCheckout({ amount: 10000 });
52
- expect(true).toBe(false);
53
- }
54
- catch (e) {
55
- expect(e.code).toBe('NOT_INITIALIZED');
56
- expect(e.message).toContain('initialized');
57
- }
58
- expect(mockPresentCheckout).not.toHaveBeenCalled();
59
- });
60
- it('calls native presentCheckout with customerId and amount after initialize', async () => {
61
- initialize({ apiKey: 'sk_xxx' });
62
- const result = await presentCheckout({ customerId: 'cus_1', amount: 10000 });
63
- expect(mockPresentCheckout).toHaveBeenCalledWith('cus_1', 10000);
64
- expect(result).toEqual({ id: 'ci_1', amount: 10000 });
65
- });
66
- it('passes null for customerId when not provided', async () => {
67
- initialize({ apiKey: 'sk_xxx' });
68
- await presentCheckout({ amount: 5000 });
69
- expect(mockPresentCheckout).toHaveBeenCalledWith(null, 5000);
70
- });
71
- });
72
- describe('presentCart', () => {
73
- const items = [
74
- { id: '1', title: 'Item A', amountInCents: 1000, imageUrl: 'https://example.com/a.jpg' },
75
- ];
76
- it('throws NOT_INITIALIZED if initialize was not called', async () => {
77
- try {
78
- await presentCart({ items, shippingAmountInCents: 500 });
79
- expect(true).toBe(false);
80
- }
81
- catch (e) {
82
- expect(e.code).toBe('NOT_INITIALIZED');
83
- }
84
- expect(mockPresentCart).not.toHaveBeenCalled();
85
- });
86
- it('calls native presentCart with customerId, items, shipping after initialize', async () => {
87
- initialize({ apiKey: 'sk_xxx' });
88
- const result = await presentCart({
89
- customerId: 'cus_2',
90
- items,
91
- shippingAmountInCents: 500,
92
- });
93
- expect(mockPresentCart).toHaveBeenCalledWith('cus_2', items, 500);
94
- expect(result).toEqual({ id: 'ci_2', amount: 15000 });
95
- });
96
- it('passes null for customerId when not provided', async () => {
97
- initialize({ apiKey: 'sk_xxx' });
98
- await presentCart({ items, shippingAmountInCents: 0 });
99
- expect(mockPresentCart).toHaveBeenCalledWith(null, items, 0);
100
- });
101
- });
@@ -1,30 +0,0 @@
1
- /**
2
- * <FrameApplePayButton /> — iOS-only React Native view that wraps Frame iOS SDK's
3
- * native FrameApplePayButton (PassKit + automatic device attestation).
4
- *
5
- * On non-iOS platforms this component renders nothing, so consumers can place it
6
- * unconditionally in their JSX.
7
- */
8
- import * as React from 'react';
9
- import { type NativeSyntheticEvent, type ViewProps } from 'react-native';
10
- import type { ApplePayButtonStyle, ApplePayButtonType, ApplePayOwner, FrameApplePayResultEvent } from '../types';
11
- export interface FrameApplePayButtonProps extends ViewProps {
12
- /** Payment amount in cents. */
13
- amount: number;
14
- /** ISO 4217 currency code. Defaults to 'usd'. */
15
- currency?: string;
16
- /** Customer or account that owns the resulting payment method. */
17
- owner: ApplePayOwner;
18
- /** Apple Pay merchant ID configured in your Apple Developer account. */
19
- merchantId: string;
20
- /** When true, the button renders a "Or" divider beneath itself for inline checkout layouts. */
21
- addCheckoutDivider?: boolean;
22
- /** PassKit button type. Defaults to 'buy'. */
23
- buttonType?: ApplePayButtonType;
24
- /** PassKit button style. Defaults to 'black'. */
25
- buttonStyle?: ApplePayButtonStyle;
26
- /** Fired when payment completes, fails, or the button reports an error. */
27
- onResult: (event: NativeSyntheticEvent<FrameApplePayResultEvent>) => void;
28
- }
29
- export declare const FrameApplePayButton: React.FC<FrameApplePayButtonProps>;
30
- //# sourceMappingURL=FrameApplePayButton.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FrameApplePayButton.d.ts","sourceRoot":"","sources":["../../src/components/FrameApplePayButton.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAIL,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,wBAAwB,EACzB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,wBAAyB,SAAQ,SAAS;IACzD,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,KAAK,EAAE,aAAa,CAAC;IACrB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,iDAAiD;IACjD,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,wBAAwB,CAAC,KAAK,IAAI,CAAC;CAC3E;AA+BD,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAclE,CAAC"}
@@ -1,42 +0,0 @@
1
- /**
2
- * <FrameApplePayButton /> — iOS-only React Native view that wraps Frame iOS SDK's
3
- * native FrameApplePayButton (PassKit + automatic device attestation).
4
- *
5
- * On non-iOS platforms this component renders nothing, so consumers can place it
6
- * unconditionally in their JSX.
7
- */
8
- import * as React from 'react';
9
- import { Platform, StyleSheet, requireNativeComponent, } from 'react-native';
10
- const NativeFrameApplePayButton = Platform.OS === 'ios'
11
- ? requireNativeComponent('FrameApplePayButtonView')
12
- : null;
13
- let warnedAboutOwner = false;
14
- function warnIfBadOwner(owner) {
15
- if (!owner ||
16
- (owner.type !== 'customer' && owner.type !== 'account') ||
17
- typeof owner.id !== 'string' ||
18
- owner.id.length === 0) {
19
- if (!warnedAboutOwner) {
20
- warnedAboutOwner = true;
21
- // eslint-disable-next-line no-console
22
- console.warn('[FrameApplePayButton] `owner` must be { type: "customer" | "account", id: string }. The button will not render until a valid owner is provided.');
23
- }
24
- return false;
25
- }
26
- return true;
27
- }
28
- export const FrameApplePayButton = (props) => {
29
- if (Platform.OS !== 'ios' || NativeFrameApplePayButton === null) {
30
- return null;
31
- }
32
- if (!warnIfBadOwner(props.owner)) {
33
- return null;
34
- }
35
- const { style, ...rest } = props;
36
- return (<NativeFrameApplePayButton {...rest} style={[styles.button, style]}/>);
37
- };
38
- const styles = StyleSheet.create({
39
- button: {
40
- height: 50,
41
- },
42
- });
@@ -1,28 +0,0 @@
1
- /**
2
- * <FrameGooglePayButton /> — Android-only React Native view that wraps Frame Android SDK's
3
- * native FrameGooglePayButton (Google Pay PaymentsClient + readiness check).
4
- *
5
- * On non-Android platforms this component renders nothing, so consumers can place it
6
- * unconditionally in their JSX.
7
- */
8
- import * as React from 'react';
9
- import { type NativeSyntheticEvent, type ViewProps } from 'react-native';
10
- import type { FrameGooglePayResultEvent } from '../types';
11
- export interface FrameGooglePayButtonProps extends ViewProps {
12
- /** Payment amount in cents. */
13
- amountCents: number;
14
- /** Optional Frame customer ID to associate the resulting payment method with. */
15
- customerId?: string;
16
- /** ISO 4217 currency code. Defaults to 'USD'. */
17
- currencyCode?: string;
18
- /** Optional override for the Google Pay merchant ID. */
19
- googlePayMerchantId?: string;
20
- /** Fired when payment completes, fails, or the user cancels the Google Pay sheet. */
21
- onResult: (event: NativeSyntheticEvent<FrameGooglePayResultEvent>) => void;
22
- /** Fired when Google Pay readiness changes (button shows/hides itself accordingly). */
23
- onReadinessChanged?: (event: NativeSyntheticEvent<{
24
- isReady: boolean;
25
- }>) => void;
26
- }
27
- export declare const FrameGooglePayButton: React.FC<FrameGooglePayButtonProps>;
28
- //# sourceMappingURL=FrameGooglePayButton.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FrameGooglePayButton.d.ts","sourceRoot":"","sources":["../../src/components/FrameGooglePayButton.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAIL,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAE1D,MAAM,WAAW,yBAA0B,SAAQ,SAAS;IAC1D,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qFAAqF;IACrF,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,yBAAyB,CAAC,KAAK,IAAI,CAAC;IAC3E,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,KAAK,IAAI,CAAC;CAClF;AAOD,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAWpE,CAAC"}
@@ -1,24 +0,0 @@
1
- /**
2
- * <FrameGooglePayButton /> — Android-only React Native view that wraps Frame Android SDK's
3
- * native FrameGooglePayButton (Google Pay PaymentsClient + readiness check).
4
- *
5
- * On non-Android platforms this component renders nothing, so consumers can place it
6
- * unconditionally in their JSX.
7
- */
8
- import * as React from 'react';
9
- import { Platform, StyleSheet, requireNativeComponent, } from 'react-native';
10
- const NativeFrameGooglePayButton = Platform.OS === 'android'
11
- ? requireNativeComponent('FrameGooglePayButtonView')
12
- : null;
13
- export const FrameGooglePayButton = (props) => {
14
- if (Platform.OS !== 'android' || NativeFrameGooglePayButton === null) {
15
- return null;
16
- }
17
- const { style, ...rest } = props;
18
- return (<NativeFrameGooglePayButton {...rest} style={[styles.button, style]}/>);
19
- };
20
- const styles = StyleSheet.create({
21
- button: {
22
- height: 48,
23
- },
24
- });
@@ -1,5 +0,0 @@
1
- export { FrameApplePayButton } from './FrameApplePayButton';
2
- export type { FrameApplePayButtonProps } from './FrameApplePayButton';
3
- export { FrameGooglePayButton } from './FrameGooglePayButton';
4
- export type { FrameGooglePayButtonProps } from './FrameGooglePayButton';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -1,2 +0,0 @@
1
- export { FrameApplePayButton } from './FrameApplePayButton';
2
- export { FrameGooglePayButton } from './FrameGooglePayButton';