@onramper/onramper-react-native 1.2.2 → 1.3.1

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +249 -0
  2. package/README.md +64 -4
  3. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64/OnramperSDK.framework/Modules/OnramperSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  4. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64/OnramperSDK.framework/Modules/OnramperSDK.swiftmodule/arm64-apple-ios.swiftinterface +110 -4
  5. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64/OnramperSDK.framework/OnramperSDK +0 -0
  6. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64/dSYMs/OnramperSDK.framework.dSYM/Contents/Resources/DWARF/OnramperSDK +0 -0
  7. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64/dSYMs/OnramperSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/OnramperSDK.yml +3562 -2684
  8. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64_x86_64-simulator/OnramperSDK.framework/Modules/OnramperSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  9. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64_x86_64-simulator/OnramperSDK.framework/Modules/OnramperSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +110 -4
  10. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64_x86_64-simulator/OnramperSDK.framework/Modules/OnramperSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  11. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64_x86_64-simulator/OnramperSDK.framework/Modules/OnramperSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +110 -4
  12. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64_x86_64-simulator/OnramperSDK.framework/OnramperSDK +0 -0
  13. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/OnramperSDK.framework.dSYM/Contents/Resources/DWARF/OnramperSDK +0 -0
  14. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/OnramperSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/OnramperSDK.yml +3562 -2684
  15. package/ios/Frameworks/OnramperSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/OnramperSDK.framework.dSYM/Contents/Resources/Relocations/x86_64/OnramperSDK.yml +3525 -2651
  16. package/ios/HybridOnramperCheckoutButton.swift +77 -3
  17. package/ios/HybridOnramperNitro.swift +142 -78
  18. package/ios/OnramperSDKBridge.swift +19 -2
  19. package/ios/PreparedIntentRegistry.swift +124 -6
  20. package/ios/SDKLogRelay.swift +41 -0
  21. package/lib/commonjs/CheckoutButton.js +34 -0
  22. package/lib/commonjs/CheckoutButton.js.map +1 -0
  23. package/lib/commonjs/OnramperClient.js +81 -12
  24. package/lib/commonjs/OnramperClient.js.map +1 -1
  25. package/lib/commonjs/errors.js +19 -5
  26. package/lib/commonjs/errors.js.map +1 -1
  27. package/lib/commonjs/generated/OnramperCheckoutButtonConfig.json +1 -0
  28. package/lib/module/CheckoutButton.js +30 -0
  29. package/lib/module/CheckoutButton.js.map +1 -0
  30. package/lib/module/OnramperClient.js +81 -12
  31. package/lib/module/OnramperClient.js.map +1 -1
  32. package/lib/module/errors.js +19 -5
  33. package/lib/module/errors.js.map +1 -1
  34. package/lib/module/generated/OnramperCheckoutButtonConfig.json +1 -0
  35. package/lib/typescript/commonjs/src/CheckoutButton.d.ts +20 -0
  36. package/lib/typescript/commonjs/src/CheckoutButton.d.ts.map +1 -0
  37. package/lib/typescript/commonjs/src/OnramperClient.d.ts +10 -1
  38. package/lib/typescript/commonjs/src/OnramperClient.d.ts.map +1 -1
  39. package/lib/typescript/commonjs/src/errors.d.ts +6 -1
  40. package/lib/typescript/commonjs/src/errors.d.ts.map +1 -1
  41. package/lib/typescript/commonjs/src/events.d.ts +10 -0
  42. package/lib/typescript/commonjs/src/events.d.ts.map +1 -1
  43. package/lib/typescript/commonjs/src/index.d.ts +1 -1
  44. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  45. package/lib/typescript/commonjs/src/specs/OnramperCheckoutButton.nitro.d.ts +6 -0
  46. package/lib/typescript/commonjs/src/specs/OnramperCheckoutButton.nitro.d.ts.map +1 -1
  47. package/lib/typescript/commonjs/src/specs/OnramperNitro.nitro.d.ts +4 -0
  48. package/lib/typescript/commonjs/src/specs/OnramperNitro.nitro.d.ts.map +1 -1
  49. package/lib/typescript/commonjs/src/types.d.ts +32 -3
  50. package/lib/typescript/commonjs/src/types.d.ts.map +1 -1
  51. package/lib/typescript/module/src/CheckoutButton.d.ts +20 -0
  52. package/lib/typescript/module/src/CheckoutButton.d.ts.map +1 -0
  53. package/lib/typescript/module/src/OnramperClient.d.ts +10 -1
  54. package/lib/typescript/module/src/OnramperClient.d.ts.map +1 -1
  55. package/lib/typescript/module/src/errors.d.ts +6 -1
  56. package/lib/typescript/module/src/errors.d.ts.map +1 -1
  57. package/lib/typescript/module/src/events.d.ts +10 -0
  58. package/lib/typescript/module/src/events.d.ts.map +1 -1
  59. package/lib/typescript/module/src/index.d.ts +1 -1
  60. package/lib/typescript/module/src/index.d.ts.map +1 -1
  61. package/lib/typescript/module/src/specs/OnramperCheckoutButton.nitro.d.ts +6 -0
  62. package/lib/typescript/module/src/specs/OnramperCheckoutButton.nitro.d.ts.map +1 -1
  63. package/lib/typescript/module/src/specs/OnramperNitro.nitro.d.ts +4 -0
  64. package/lib/typescript/module/src/specs/OnramperNitro.nitro.d.ts.map +1 -1
  65. package/lib/typescript/module/src/types.d.ts +32 -3
  66. package/lib/typescript/module/src/types.d.ts.map +1 -1
  67. package/nitrogen/generated/ios/OnramperReactNative-Swift-Cxx-Bridge.cpp +11 -3
  68. package/nitrogen/generated/ios/OnramperReactNative-Swift-Cxx-Bridge.hpp +44 -7
  69. package/nitrogen/generated/ios/c++/HybridOnramperCheckoutButtonSpecSwift.hpp +9 -0
  70. package/nitrogen/generated/ios/c++/HybridOnramperNitroSpecSwift.hpp +11 -2
  71. package/nitrogen/generated/ios/c++/views/HybridOnramperCheckoutButtonComponent.mm +5 -0
  72. package/nitrogen/generated/ios/swift/Func_void_double.swift +46 -0
  73. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +5 -5
  74. package/nitrogen/generated/ios/swift/HybridOnramperCheckoutButtonSpec.swift +1 -0
  75. package/nitrogen/generated/ios/swift/HybridOnramperCheckoutButtonSpec_cxx.swift +32 -0
  76. package/nitrogen/generated/ios/swift/HybridOnramperNitroSpec.swift +2 -1
  77. package/nitrogen/generated/ios/swift/HybridOnramperNitroSpec_cxx.swift +32 -11
  78. package/nitrogen/generated/ios/swift/OnramperNitroConfig.swift +16 -6
  79. package/nitrogen/generated/shared/c++/HybridOnramperCheckoutButtonSpec.cpp +2 -0
  80. package/nitrogen/generated/shared/c++/HybridOnramperCheckoutButtonSpec.hpp +4 -0
  81. package/nitrogen/generated/shared/c++/HybridOnramperNitroSpec.cpp +2 -0
  82. package/nitrogen/generated/shared/c++/HybridOnramperNitroSpec.hpp +3 -2
  83. package/nitrogen/generated/shared/c++/OnramperNitroConfig.hpp +10 -2
  84. package/nitrogen/generated/shared/c++/views/HybridOnramperCheckoutButtonComponent.cpp +11 -0
  85. package/nitrogen/generated/shared/c++/views/HybridOnramperCheckoutButtonComponent.hpp +3 -2
  86. package/nitrogen/generated/shared/json/OnramperCheckoutButtonConfig.json +1 -0
  87. package/package.json +5 -2
  88. package/src/CheckoutButton.ts +28 -0
  89. package/src/OnramperClient.ts +82 -9
  90. package/src/errors.ts +29 -6
  91. package/src/events.ts +5 -0
  92. package/src/generated/OnramperCheckoutButtonConfig.json +1 -0
  93. package/src/index.ts +3 -0
  94. package/src/specs/OnramperCheckoutButton.nitro.ts +6 -0
  95. package/src/specs/OnramperNitro.nitro.ts +5 -0
  96. package/src/types.ts +36 -3
@@ -10,7 +10,7 @@ import NitroModules
10
10
  /// See ``HybridOnramperNitroSpec``
11
11
  public protocol HybridOnramperNitroSpec_protocol: HybridObject {
12
12
  // Properties
13
-
13
+ var sdkVersion: String { get }
14
14
 
15
15
  // Methods
16
16
  func configure(config: OnramperNitroConfig) throws -> Promise<Void>
@@ -19,6 +19,7 @@ public protocol HybridOnramperNitroSpec_protocol: HybridObject {
19
19
  func signOut() throws -> Promise<Void>
20
20
  func getCheckoutRequirements(requestJson: String, prefillJson: String, styleJson: String) throws -> Promise<PreparedIntentResult>
21
21
  func cancelPreparedIntent(intentHandle: String) throws -> Promise<Void>
22
+ func setLogListener(onLog: @escaping (_ recordJson: String) -> Void) throws -> Void
22
23
  func setStateListener(onState: @escaping (_ stateJson: String) -> Void) throws -> Void
23
24
  func setEventListener(onEvent: @escaping (_ eventJson: String) -> Void) throws -> Void
24
25
  func setTransactionIdListener(onTransactionId: @escaping (_ transactionId: String?) -> Void) throws -> Void
@@ -84,7 +84,7 @@ open class HybridOnramperNitroSpec_cxx {
84
84
  }
85
85
  }
86
86
 
87
-
87
+
88
88
 
89
89
  /**
90
90
  * Get the memory size of the Swift class (plus size of any other allocations)
@@ -121,7 +121,12 @@ open class HybridOnramperNitroSpec_cxx {
121
121
  }
122
122
 
123
123
  // Properties
124
-
124
+ public final var sdkVersion: std.string {
125
+ @inline(__always)
126
+ get {
127
+ return std.string(self.__implementation.sdkVersion)
128
+ }
129
+ }
125
130
 
126
131
  // Methods
127
132
  @inline(__always)
@@ -142,7 +147,7 @@ open class HybridOnramperNitroSpec_cxx {
142
147
  return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
143
148
  }
144
149
  }
145
-
150
+
146
151
  @inline(__always)
147
152
  public final func initialize(sessionId: std.string, sessionToken: std.string) -> bridge.Result_std__shared_ptr_Promise_void___ {
148
153
  do {
@@ -161,7 +166,7 @@ open class HybridOnramperNitroSpec_cxx {
161
166
  return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
162
167
  }
163
168
  }
164
-
169
+
165
170
  @inline(__always)
166
171
  public final func reset() -> bridge.Result_std__shared_ptr_Promise_void___ {
167
172
  do {
@@ -180,7 +185,7 @@ open class HybridOnramperNitroSpec_cxx {
180
185
  return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
181
186
  }
182
187
  }
183
-
188
+
184
189
  @inline(__always)
185
190
  public final func signOut() -> bridge.Result_std__shared_ptr_Promise_void___ {
186
191
  do {
@@ -199,7 +204,7 @@ open class HybridOnramperNitroSpec_cxx {
199
204
  return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
200
205
  }
201
206
  }
202
-
207
+
203
208
  @inline(__always)
204
209
  public final func getCheckoutRequirements(requestJson: std.string, prefillJson: std.string, styleJson: std.string) -> bridge.Result_std__shared_ptr_Promise_PreparedIntentResult___ {
205
210
  do {
@@ -218,7 +223,7 @@ open class HybridOnramperNitroSpec_cxx {
218
223
  return bridge.create_Result_std__shared_ptr_Promise_PreparedIntentResult___(__exceptionPtr)
219
224
  }
220
225
  }
221
-
226
+
222
227
  @inline(__always)
223
228
  public final func cancelPreparedIntent(intentHandle: std.string) -> bridge.Result_std__shared_ptr_Promise_void___ {
224
229
  do {
@@ -237,7 +242,23 @@ open class HybridOnramperNitroSpec_cxx {
237
242
  return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
238
243
  }
239
244
  }
240
-
245
+
246
+ @inline(__always)
247
+ public final func setLogListener(onLog: bridge.Func_void_std__string) -> bridge.Result_void_ {
248
+ do {
249
+ try self.__implementation.setLogListener(onLog: { () -> (String) -> Void in
250
+ let __wrappedFunction = bridge.wrap_Func_void_std__string(onLog)
251
+ return { (__recordJson: String) -> Void in
252
+ __wrappedFunction.call(std.string(__recordJson))
253
+ }
254
+ }())
255
+ return bridge.create_Result_void_()
256
+ } catch (let __error) {
257
+ let __exceptionPtr = __error.toCpp()
258
+ return bridge.create_Result_void_(__exceptionPtr)
259
+ }
260
+ }
261
+
241
262
  @inline(__always)
242
263
  public final func setStateListener(onState: bridge.Func_void_std__string) -> bridge.Result_void_ {
243
264
  do {
@@ -253,7 +274,7 @@ open class HybridOnramperNitroSpec_cxx {
253
274
  return bridge.create_Result_void_(__exceptionPtr)
254
275
  }
255
276
  }
256
-
277
+
257
278
  @inline(__always)
258
279
  public final func setEventListener(onEvent: bridge.Func_void_std__string) -> bridge.Result_void_ {
259
280
  do {
@@ -269,7 +290,7 @@ open class HybridOnramperNitroSpec_cxx {
269
290
  return bridge.create_Result_void_(__exceptionPtr)
270
291
  }
271
292
  }
272
-
293
+
273
294
  @inline(__always)
274
295
  public final func setTransactionIdListener(onTransactionId: bridge.Func_void_std__optional_std__string_) -> bridge.Result_void_ {
275
296
  do {
@@ -291,7 +312,7 @@ open class HybridOnramperNitroSpec_cxx {
291
312
  return bridge.create_Result_void_(__exceptionPtr)
292
313
  }
293
314
  }
294
-
315
+
295
316
  @inline(__always)
296
317
  public final func setSessionExpirationHandler(handler: bridge.Func_std__shared_ptr_Promise_std__shared_ptr_Promise_NitroSessionCredentials____) -> bridge.Result_void_ {
297
318
  do {
@@ -18,32 +18,42 @@ public extension OnramperNitroConfig {
18
18
  /**
19
19
  * Create a new instance of `OnramperNitroConfig`.
20
20
  */
21
- init(apiKey: String, clientId: String, environment: String, theme: String, logLevel: String) {
22
- self.init(std.string(apiKey), std.string(clientId), std.string(environment), std.string(theme), std.string(logLevel))
21
+ init(apiKey: String, clientId: String, environment: String, theme: String, logLevel: String, isEventLoggingEnabled: Bool, isEventConsoleLoggingEnabled: Bool) {
22
+ self.init(std.string(apiKey), std.string(clientId), std.string(environment), std.string(theme), std.string(logLevel), isEventLoggingEnabled, isEventConsoleLoggingEnabled)
23
23
  }
24
24
 
25
25
  @inline(__always)
26
26
  var apiKey: String {
27
27
  return String(self.__apiKey)
28
28
  }
29
-
29
+
30
30
  @inline(__always)
31
31
  var clientId: String {
32
32
  return String(self.__clientId)
33
33
  }
34
-
34
+
35
35
  @inline(__always)
36
36
  var environment: String {
37
37
  return String(self.__environment)
38
38
  }
39
-
39
+
40
40
  @inline(__always)
41
41
  var theme: String {
42
42
  return String(self.__theme)
43
43
  }
44
-
44
+
45
45
  @inline(__always)
46
46
  var logLevel: String {
47
47
  return String(self.__logLevel)
48
48
  }
49
+
50
+ @inline(__always)
51
+ var isEventLoggingEnabled: Bool {
52
+ return self.__isEventLoggingEnabled
53
+ }
54
+
55
+ @inline(__always)
56
+ var isEventConsoleLoggingEnabled: Bool {
57
+ return self.__isEventConsoleLoggingEnabled
58
+ }
49
59
  }
@@ -16,6 +16,8 @@ namespace margelo::nitro::onramper {
16
16
  registerHybrids(this, [](Prototype& prototype) {
17
17
  prototype.registerHybridGetter("intentHandle", &HybridOnramperCheckoutButtonSpec::getIntentHandle);
18
18
  prototype.registerHybridSetter("intentHandle", &HybridOnramperCheckoutButtonSpec::setIntentHandle);
19
+ prototype.registerHybridGetter("onContentHeightChange", &HybridOnramperCheckoutButtonSpec::getOnContentHeightChange);
20
+ prototype.registerHybridSetter("onContentHeightChange", &HybridOnramperCheckoutButtonSpec::setOnContentHeightChange);
19
21
  });
20
22
  }
21
23
 
@@ -16,6 +16,8 @@
16
16
 
17
17
 
18
18
  #include <string>
19
+ #include <functional>
20
+ #include <optional>
19
21
 
20
22
  namespace margelo::nitro::onramper {
21
23
 
@@ -46,6 +48,8 @@ namespace margelo::nitro::onramper {
46
48
  // Properties
47
49
  virtual std::string getIntentHandle() = 0;
48
50
  virtual void setIntentHandle(const std::string& intentHandle) = 0;
51
+ virtual std::optional<std::function<void(double /* height */)>> getOnContentHeightChange() = 0;
52
+ virtual void setOnContentHeightChange(const std::optional<std::function<void(double /* height */)>>& onContentHeightChange) = 0;
49
53
 
50
54
  public:
51
55
  // Methods
@@ -14,12 +14,14 @@ namespace margelo::nitro::onramper {
14
14
  HybridObject::loadHybridMethods();
15
15
  // load custom methods/properties
16
16
  registerHybrids(this, [](Prototype& prototype) {
17
+ prototype.registerHybridGetter("sdkVersion", &HybridOnramperNitroSpec::getSdkVersion);
17
18
  prototype.registerHybridMethod("configure", &HybridOnramperNitroSpec::configure);
18
19
  prototype.registerHybridMethod("initialize", &HybridOnramperNitroSpec::initialize);
19
20
  prototype.registerHybridMethod("reset", &HybridOnramperNitroSpec::reset);
20
21
  prototype.registerHybridMethod("signOut", &HybridOnramperNitroSpec::signOut);
21
22
  prototype.registerHybridMethod("getCheckoutRequirements", &HybridOnramperNitroSpec::getCheckoutRequirements);
22
23
  prototype.registerHybridMethod("cancelPreparedIntent", &HybridOnramperNitroSpec::cancelPreparedIntent);
24
+ prototype.registerHybridMethod("setLogListener", &HybridOnramperNitroSpec::setLogListener);
23
25
  prototype.registerHybridMethod("setStateListener", &HybridOnramperNitroSpec::setStateListener);
24
26
  prototype.registerHybridMethod("setEventListener", &HybridOnramperNitroSpec::setEventListener);
25
27
  prototype.registerHybridMethod("setTransactionIdListener", &HybridOnramperNitroSpec::setTransactionIdListener);
@@ -20,9 +20,9 @@ namespace margelo::nitro::onramper { struct PreparedIntentResult; }
20
20
  // Forward declaration of `NitroSessionCredentials` to properly resolve imports.
21
21
  namespace margelo::nitro::onramper { struct NitroSessionCredentials; }
22
22
 
23
+ #include <string>
23
24
  #include <NitroModules/Promise.hpp>
24
25
  #include "OnramperNitroConfig.hpp"
25
- #include <string>
26
26
  #include "PreparedIntentResult.hpp"
27
27
  #include <functional>
28
28
  #include <optional>
@@ -55,7 +55,7 @@ namespace margelo::nitro::onramper {
55
55
 
56
56
  public:
57
57
  // Properties
58
-
58
+ virtual std::string getSdkVersion() = 0;
59
59
 
60
60
  public:
61
61
  // Methods
@@ -65,6 +65,7 @@ namespace margelo::nitro::onramper {
65
65
  virtual std::shared_ptr<Promise<void>> signOut() = 0;
66
66
  virtual std::shared_ptr<Promise<PreparedIntentResult>> getCheckoutRequirements(const std::string& requestJson, const std::string& prefillJson, const std::string& styleJson) = 0;
67
67
  virtual std::shared_ptr<Promise<void>> cancelPreparedIntent(const std::string& intentHandle) = 0;
68
+ virtual void setLogListener(const std::function<void(const std::string& /* recordJson */)>& onLog) = 0;
68
69
  virtual void setStateListener(const std::function<void(const std::string& /* stateJson */)>& onState) = 0;
69
70
  virtual void setEventListener(const std::function<void(const std::string& /* eventJson */)>& onEvent) = 0;
70
71
  virtual void setTransactionIdListener(const std::function<void(const std::optional<std::string>& /* transactionId */)>& onTransactionId) = 0;
@@ -44,10 +44,12 @@ namespace margelo::nitro::onramper {
44
44
  std::string environment SWIFT_PRIVATE;
45
45
  std::string theme SWIFT_PRIVATE;
46
46
  std::string logLevel SWIFT_PRIVATE;
47
+ bool isEventLoggingEnabled SWIFT_PRIVATE;
48
+ bool isEventConsoleLoggingEnabled SWIFT_PRIVATE;
47
49
 
48
50
  public:
49
51
  OnramperNitroConfig() = default;
50
- explicit OnramperNitroConfig(std::string apiKey, std::string clientId, std::string environment, std::string theme, std::string logLevel): apiKey(apiKey), clientId(clientId), environment(environment), theme(theme), logLevel(logLevel) {}
52
+ explicit OnramperNitroConfig(std::string apiKey, std::string clientId, std::string environment, std::string theme, std::string logLevel, bool isEventLoggingEnabled, bool isEventConsoleLoggingEnabled): apiKey(apiKey), clientId(clientId), environment(environment), theme(theme), logLevel(logLevel), isEventLoggingEnabled(isEventLoggingEnabled), isEventConsoleLoggingEnabled(isEventConsoleLoggingEnabled) {}
51
53
 
52
54
  public:
53
55
  friend bool operator==(const OnramperNitroConfig& lhs, const OnramperNitroConfig& rhs) = default;
@@ -67,7 +69,9 @@ namespace margelo::nitro {
67
69
  JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clientId"))),
68
70
  JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "environment"))),
69
71
  JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "theme"))),
70
- JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "logLevel")))
72
+ JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "logLevel"))),
73
+ JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isEventLoggingEnabled"))),
74
+ JSIConverter<bool>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isEventConsoleLoggingEnabled")))
71
75
  );
72
76
  }
73
77
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::onramper::OnramperNitroConfig& arg) {
@@ -77,6 +81,8 @@ namespace margelo::nitro {
77
81
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "environment"), JSIConverter<std::string>::toJSI(runtime, arg.environment));
78
82
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "theme"), JSIConverter<std::string>::toJSI(runtime, arg.theme));
79
83
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "logLevel"), JSIConverter<std::string>::toJSI(runtime, arg.logLevel));
84
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "isEventLoggingEnabled"), JSIConverter<bool>::toJSI(runtime, arg.isEventLoggingEnabled));
85
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "isEventConsoleLoggingEnabled"), JSIConverter<bool>::toJSI(runtime, arg.isEventConsoleLoggingEnabled));
80
86
  return obj;
81
87
  }
82
88
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
@@ -92,6 +98,8 @@ namespace margelo::nitro {
92
98
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "environment")))) return false;
93
99
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "theme")))) return false;
94
100
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "logLevel")))) return false;
101
+ if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isEventLoggingEnabled")))) return false;
102
+ if (!JSIConverter<bool>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isEventConsoleLoggingEnabled")))) return false;
95
103
  return true;
96
104
  }
97
105
  };
@@ -36,6 +36,16 @@ namespace margelo::nitro::onramper::views {
36
36
  throw std::runtime_error(std::string("OnramperCheckoutButton.intentHandle: ") + exc.what());
37
37
  }
38
38
  }()),
39
+ onContentHeightChange([&]() -> CachedProp<std::optional<std::function<void(double /* height */)>>> {
40
+ try {
41
+ const react::RawValue* rawValue = rawProps.at("onContentHeightChange", nullptr, nullptr);
42
+ if (rawValue == nullptr) return sourceProps.onContentHeightChange;
43
+ const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
44
+ return CachedProp<std::optional<std::function<void(double /* height */)>>>::fromRawValue(*runtime, value.asObject(*runtime).getProperty(*runtime, PropNameIDCache::get(*runtime, "f")), sourceProps.onContentHeightChange);
45
+ } catch (const std::exception& exc) {
46
+ throw std::runtime_error(std::string("OnramperCheckoutButton.onContentHeightChange: ") + exc.what());
47
+ }
48
+ }()),
39
49
  hybridRef([&]() -> CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridOnramperCheckoutButtonSpec>& /* ref */)>>> {
40
50
  try {
41
51
  const react::RawValue* rawValue = rawProps.at("hybridRef", nullptr, nullptr);
@@ -50,6 +60,7 @@ namespace margelo::nitro::onramper::views {
50
60
  bool HybridOnramperCheckoutButtonProps::filterObjectKeys(const std::string& propName) {
51
61
  switch (hashString(propName)) {
52
62
  case hashString("intentHandle"): return true;
63
+ case hashString("onContentHeightChange"): return true;
53
64
  case hashString("hybridRef"): return true;
54
65
  default: return false;
55
66
  }
@@ -17,10 +17,10 @@
17
17
  #include <react/renderer/components/view/ViewProps.h>
18
18
 
19
19
  #include <string>
20
- #include <memory>
21
- #include "HybridOnramperCheckoutButtonSpec.hpp"
22
20
  #include <functional>
23
21
  #include <optional>
22
+ #include <memory>
23
+ #include "HybridOnramperCheckoutButtonSpec.hpp"
24
24
 
25
25
  namespace margelo::nitro::onramper::views {
26
26
 
@@ -43,6 +43,7 @@ namespace margelo::nitro::onramper::views {
43
43
 
44
44
  public:
45
45
  CachedProp<std::string> intentHandle;
46
+ CachedProp<std::optional<std::function<void(double /* height */)>>> onContentHeightChange;
46
47
  CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridOnramperCheckoutButtonSpec>& /* ref */)>>> hybridRef;
47
48
 
48
49
  private:
@@ -5,6 +5,7 @@
5
5
  "directEventTypes": {},
6
6
  "validAttributes": {
7
7
  "intentHandle": true,
8
+ "onContentHeightChange": true,
8
9
  "hybridRef": true
9
10
  }
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onramper/onramper-react-native",
3
- "version": "1.2.2",
3
+ "version": "1.3.1",
4
4
  "description": "React Native wrapper for the Onramper iOS SDK",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",
@@ -41,6 +41,7 @@
41
41
  "lint": "biome check src",
42
42
  "format": "biome format --write src",
43
43
  "test": "jest",
44
+ "test:native": "bash scripts/test-native.sh",
44
45
  "typecheck": "tsc --noEmit",
45
46
  "nitrogen": "nitrogen && node scripts/sync-view-config.js",
46
47
  "prepare": "bob build",
@@ -64,7 +65,7 @@
64
65
  "license": "Apache-2.0",
65
66
  "homepage": "https://github.com/onramper/onramper-react-native#readme",
66
67
  "onramperSDK": {
67
- "checksum": "754184c10a736e1db3292b592ca634ddbaa61dd01540b60610df4aa73a61de9a"
68
+ "checksum": "c003eb348062fb755d3de304f1f7ea4f1a7253192fa7e33adb794f2ce1d90d6a"
68
69
  },
69
70
  "peerDependencies": {
70
71
  "react": ">=19.0.0",
@@ -76,12 +77,14 @@
76
77
  "@expo/config-plugins": "^10.0.0",
77
78
  "@types/jest": "^29.5.14",
78
79
  "@types/react": "~19.2.0",
80
+ "@types/react-test-renderer": "^19.3.0",
79
81
  "jest": "^29.7.0",
80
82
  "nitrogen": "^0.35.9",
81
83
  "react": "19.2.3",
82
84
  "react-native": "0.85.3",
83
85
  "react-native-builder-bob": "^0.43.0",
84
86
  "react-native-nitro-modules": "^0.35.9",
87
+ "react-test-renderer": "^19.2.3",
85
88
  "ts-jest": "^29.4.10",
86
89
  "typescript": "~5.8.3"
87
90
  },
@@ -0,0 +1,28 @@
1
+ import { createElement, useMemo, useState } from 'react';
2
+ import { callback } from 'react-native-nitro-modules';
3
+
4
+ import { OnramperCheckoutButtonView } from './OnramperCheckoutButtonView';
5
+
6
+ // Height of the bare Buy button. Used until native reports the measured content
7
+ // height so the first frame isn't collapsed.
8
+ export const CHECKOUT_BUTTON_FALLBACK_HEIGHT = 56;
9
+
10
+ export interface CheckoutButtonProps {
11
+ intentHandle: string;
12
+ }
13
+
14
+ /**
15
+ * Sizes the native checkout button to its SwiftUI content. The content grows when
16
+ * the SDK shows ToS text under the Buy button (which can change after mount), and
17
+ * Yoga can't measure a SwiftUI view — so native reports the height and it is
18
+ * applied here as an explicit `height`.
19
+ */
20
+ export function CheckoutButton({ intentHandle }: CheckoutButtonProps) {
21
+ const [height, setHeight] = useState<number | null>(null);
22
+ const onContentHeightChange = useMemo(() => callback((h: number) => setHeight(Math.ceil(h))), []);
23
+ return createElement(OnramperCheckoutButtonView, {
24
+ intentHandle,
25
+ onContentHeightChange,
26
+ style: { width: '100%', height: height ?? CHECKOUT_BUTTON_FALLBACK_HEIGHT },
27
+ });
28
+ }
@@ -1,6 +1,6 @@
1
1
  import { type ReactElement, createElement } from 'react';
2
2
 
3
- import { OnramperCheckoutButtonView } from './OnramperCheckoutButtonView';
3
+ import { CheckoutButton } from './CheckoutButton';
4
4
  import { createOnramperNative } from './OnramperNative';
5
5
  import { OnramperError } from './errors';
6
6
  import type { CheckoutEvent, EventName, EventPayload } from './events';
@@ -8,6 +8,7 @@ import type {
8
8
  CheckoutButtonStyle,
9
9
  CheckoutRequest,
10
10
  OnramperConfiguration,
11
+ OnramperLogRecord,
11
12
  OnramperState,
12
13
  OnramperUserPrefill,
13
14
  QuoteResponse,
@@ -28,6 +29,19 @@ export interface GetCheckoutRequirementsResult {
28
29
  * unions, then fanned out to any number of listeners.
29
30
  */
30
31
  export class OnramperClient {
32
+ /**
33
+ * Version of the native Onramper iOS SDK loaded by this app (not the RN
34
+ * package version). No client configuration or session is required. iOS only.
35
+ */
36
+ static get sdkVersion(): string {
37
+ const native = createOnramperNative();
38
+ try {
39
+ return native.sdkVersion;
40
+ } finally {
41
+ native.dispose();
42
+ }
43
+ }
44
+
31
45
  state: OnramperState = { kind: 'idle' };
32
46
  lastError: OnramperError | null = null;
33
47
  currentTransactionId: string | null = null;
@@ -42,10 +56,24 @@ export class OnramperClient {
42
56
  // Resolved when the constructor-issued configure() completes. Public methods
43
57
  // that need the native client await this first.
44
58
  private readonly configured: Promise<void>;
59
+ private destroyed = false;
45
60
 
46
61
  constructor(config: OnramperConfiguration) {
62
+ if (config.logHandler) {
63
+ const handler = config.logHandler;
64
+ this.native.setLogListener((json) => {
65
+ if (this.destroyed) return;
66
+ try {
67
+ handler(JSON.parse(json) as OnramperLogRecord);
68
+ } catch {
69
+ // Diagnostics must never interrupt checkout; do not log callback data.
70
+ console.warn('Onramper logHandler failed.');
71
+ }
72
+ });
73
+ }
47
74
  // Single native state callback → update the mirror + fan out to listeners.
48
75
  this.native.setStateListener((json) => {
76
+ if (this.destroyed) return;
49
77
  const s = JSON.parse(json) as OnramperState;
50
78
  this.state = s;
51
79
  if (s.kind === 'failed') this.lastError = OnramperError.from(s.error);
@@ -55,6 +83,7 @@ export class OnramperClient {
55
83
  // Single native checkout-event callback → keep the transaction ID mirror
56
84
  // synchronized at finalization, then fan out to checkout listeners.
57
85
  this.native.setEventListener((json) => {
86
+ if (this.destroyed) return;
58
87
  const e = JSON.parse(json) as CheckoutEvent;
59
88
  if (e.type === 'checkoutFinalized') {
60
89
  this.updateCurrentTransactionId(e.response.onramperTransactionId);
@@ -63,6 +92,7 @@ export class OnramperClient {
63
92
  });
64
93
 
65
94
  this.native.setTransactionIdListener((transactionId) => {
95
+ if (this.destroyed) return;
66
96
  // The SDK transiently publishes nil while re-preparing after the payment
67
97
  // sheet is dismissed. The finalized transaction ID remains durable across
68
98
  // that attempt change; only explicit reset()/signOut() clear the JS mirror.
@@ -73,7 +103,9 @@ export class OnramperClient {
73
103
  // Nitro stores the async callback natively and awaits it directly — no
74
104
  // event round-trip needed.
75
105
  this.native.setSessionExpirationHandler(async () => {
106
+ this.assertActive();
76
107
  const creds = await config.onSessionExpired();
108
+ this.assertActive();
77
109
  return { sessionId: creds.sessionId, sessionToken: creds.sessionToken };
78
110
  });
79
111
 
@@ -84,10 +116,12 @@ export class OnramperClient {
84
116
  environment: config.environment,
85
117
  theme: config.theme ?? 'system',
86
118
  logLevel: config.logLevel ?? 'off',
119
+ isEventLoggingEnabled: config.isEventLoggingEnabled ?? false,
120
+ isEventConsoleLoggingEnabled: config.isEventConsoleLoggingEnabled ?? false,
87
121
  })
88
122
  .catch((e: unknown) => {
89
123
  const err = OnramperError.from(e);
90
- this.lastError = err;
124
+ if (!this.destroyed) this.lastError = err;
91
125
  throw err;
92
126
  });
93
127
  // Swallow the unhandled-rejection warning when no one awaits .configured
@@ -95,11 +129,23 @@ export class OnramperClient {
95
129
  this.configured.catch(() => undefined);
96
130
  }
97
131
 
132
+ private assertActive(): void {
133
+ if (this.destroyed) {
134
+ throw new OnramperError({
135
+ code: 'clientDestroyed',
136
+ message: 'This OnramperClient has been destroyed. Create a new client before making SDK calls.',
137
+ userMessage: 'This checkout session has ended. Please reopen checkout.',
138
+ });
139
+ }
140
+ }
141
+
98
142
  private updateCurrentTransactionId(next: string | null): void {
143
+ if (this.destroyed) return;
99
144
  if (next === this.currentTransactionId) return;
100
145
 
101
146
  this.currentTransactionId = next;
102
147
  for (const fn of [...this.transactionIdListeners]) {
148
+ if (this.destroyed) break;
103
149
  try {
104
150
  fn(next);
105
151
  } catch (error: unknown) {
@@ -110,19 +156,27 @@ export class OnramperClient {
110
156
 
111
157
  async initialize(creds: SessionCredentials): Promise<void> {
112
158
  try {
159
+ this.assertActive();
113
160
  await this.configured;
161
+ this.assertActive();
114
162
  await this.native.initialize(creds.sessionId, creds.sessionToken);
163
+ this.assertActive();
115
164
  } catch (e: unknown) {
165
+ this.assertActive();
116
166
  throw OnramperError.from(e);
117
167
  }
118
168
  }
119
169
 
120
170
  async reset(): Promise<void> {
121
171
  try {
172
+ this.assertActive();
122
173
  await this.configured;
174
+ this.assertActive();
123
175
  await this.native.reset();
176
+ this.assertActive();
124
177
  this.updateCurrentTransactionId(null);
125
178
  } catch (e: unknown) {
179
+ this.assertActive();
126
180
  throw OnramperError.from(e);
127
181
  }
128
182
  }
@@ -135,10 +189,14 @@ export class OnramperClient {
135
189
  */
136
190
  async signOut(): Promise<void> {
137
191
  try {
192
+ this.assertActive();
138
193
  await this.configured;
194
+ this.assertActive();
139
195
  await this.native.signOut();
196
+ this.assertActive();
140
197
  this.updateCurrentTransactionId(null);
141
198
  } catch (e: unknown) {
199
+ this.assertActive();
142
200
  throw OnramperError.from(e);
143
201
  }
144
202
  }
@@ -147,6 +205,8 @@ export class OnramperClient {
147
205
  * Fetches checkout requirements + quote and returns a native checkout button
148
206
  * to render plus the quote. The button handles login / finalize / webview
149
207
  * internally; outcomes surface via the event stream (`addEventListener`).
208
+ * A newer preparation, reset, or sign-out invalidates older unmounted buttons
209
+ * and rejects obsolete in-flight preparations with `intentInvalidated`.
150
210
  *
151
211
  * Pass `prefill` to pre-populate the OnramperID sign-in and additional-info
152
212
  * screens with values you already know about the user. It is best-effort and
@@ -164,30 +224,39 @@ export class OnramperClient {
164
224
  prefill: OnramperUserPrefill = {},
165
225
  ): Promise<GetCheckoutRequirementsResult> {
166
226
  try {
227
+ this.assertActive();
167
228
  await this.configured;
229
+ this.assertActive();
168
230
  const result = await this.native.getCheckoutRequirements(
169
231
  JSON.stringify(request),
170
232
  JSON.stringify(prefill),
171
233
  JSON.stringify(buttonStyle),
172
234
  );
235
+ this.assertActive();
173
236
  const quote = JSON.parse(result.quoteJson) as QuoteResponse;
174
- const button = createElement(OnramperCheckoutButtonView, {
175
- intentHandle: result.intentHandle,
176
- style: { width: '100%', minHeight: 56 },
177
- });
237
+ const button = createElement(CheckoutButton, { intentHandle: result.intentHandle });
178
238
  return { button, quote };
179
239
  } catch (e: unknown) {
240
+ this.assertActive();
180
241
  throw OnramperError.from(e);
181
242
  }
182
243
  }
183
244
 
184
245
  /** Discards a prepared intent (e.g. if the user navigates away before checkout). */
185
- cancelPreparedIntent(intentHandle: string): Promise<void> {
186
- return this.native.cancelPreparedIntent(intentHandle);
246
+ async cancelPreparedIntent(intentHandle: string): Promise<void> {
247
+ try {
248
+ this.assertActive();
249
+ await this.native.cancelPreparedIntent(intentHandle);
250
+ this.assertActive();
251
+ } catch (e: unknown) {
252
+ this.assertActive();
253
+ throw OnramperError.from(e);
254
+ }
187
255
  }
188
256
 
189
257
  /** Subscribe to state changes. Returns an unsubscribe function. */
190
258
  addStateListener(fn: (state: OnramperState) => void): () => void {
259
+ this.assertActive();
191
260
  this.stateListeners.add(fn);
192
261
  return () => {
193
262
  this.stateListeners.delete(fn);
@@ -196,6 +265,7 @@ export class OnramperClient {
196
265
 
197
266
  /** Subscribe to the durable Onramper transaction ID. Successful reset/signOut publish null. */
198
267
  addTransactionIdListener(fn: (transactionId: string | null) => void): () => void {
268
+ this.assertActive();
199
269
  this.transactionIdListeners.add(fn);
200
270
  return () => {
201
271
  this.transactionIdListeners.delete(fn);
@@ -204,6 +274,7 @@ export class OnramperClient {
204
274
 
205
275
  /** Subscribe to a specific checkout event. Returns an unsubscribe function. */
206
276
  addEventListener<K extends EventName>(name: K, fn: (e: EventPayload<K>) => void): () => void {
277
+ this.assertActive();
207
278
  const wrapper = (e: CheckoutEvent) => {
208
279
  if (e.type === name) fn(e as EventPayload<K>);
209
280
  };
@@ -213,8 +284,10 @@ export class OnramperClient {
213
284
  };
214
285
  }
215
286
 
216
- /** Tear down: clears JS listeners and releases the native callbacks + SDK client. */
287
+ /** Idempotent teardown. Further operations reject with `clientDestroyed`; create a new client to restart. */
217
288
  destroy(): void {
289
+ if (this.destroyed) return;
290
+ this.destroyed = true;
218
291
  this.stateListeners.clear();
219
292
  this.eventListeners.clear();
220
293
  this.transactionIdListeners.clear();