@stripe/stripe-react-native 0.52.0-crypto-onramp-2-private-beta.2 → 0.53.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.
Files changed (175) hide show
  1. package/android/.idea/caches/deviceStreaming.xml +0 -13
  2. package/android/.idea/gradle.xml +1 -0
  3. package/android/.idea/misc.xml +1 -1
  4. package/android/build.gradle +0 -14
  5. package/android/gradle.properties +1 -1
  6. package/android/local.properties +2 -2
  7. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +48 -25
  8. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +2 -0
  9. package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherFragment.kt +1 -1
  10. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +14 -13
  11. package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +1 -19
  12. package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +0 -10
  13. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +3 -12
  14. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerDelegate.java +0 -12
  15. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerInterface.java +0 -4
  16. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +4 -4
  17. package/ios/Mappers.swift +1 -134
  18. package/ios/OldArch/StripeSdkEventEmitterCompat.h +0 -1
  19. package/ios/OldArch/StripeSdkEventEmitterCompat.m +1 -7
  20. package/ios/StripeSdk.mm +7 -0
  21. package/ios/StripeSdkEmitter.swift +0 -4
  22. package/ios/StripeSdkImpl.swift +13 -584
  23. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  24. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  25. package/lib/commonjs/components/AddressSheet.js +1 -1
  26. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  27. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  28. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  29. package/lib/commonjs/components/CardField.js +1 -1
  30. package/lib/commonjs/components/CardField.js.map +1 -1
  31. package/lib/commonjs/components/CardForm.js +1 -1
  32. package/lib/commonjs/components/CardForm.js.map +1 -1
  33. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  34. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  35. package/lib/commonjs/components/StripeContainer.js +1 -1
  36. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  37. package/lib/commonjs/components/StripeProvider.js +1 -1
  38. package/lib/commonjs/components/StripeProvider.js.map +1 -1
  39. package/lib/commonjs/events.js +1 -1
  40. package/lib/commonjs/events.js.map +1 -1
  41. package/lib/commonjs/functions.js +1 -1
  42. package/lib/commonjs/functions.js.map +1 -1
  43. package/lib/commonjs/index.js +1 -1
  44. package/lib/commonjs/index.js.map +1 -1
  45. package/lib/commonjs/plugin/withStripe.js +1 -1
  46. package/lib/commonjs/plugin/withStripe.js.map +1 -1
  47. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  48. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  49. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  50. package/lib/commonjs/types/Errors.js +1 -1
  51. package/lib/commonjs/types/Errors.js.map +1 -1
  52. package/lib/commonjs/types/PlatformPay.js.map +1 -1
  53. package/lib/commonjs/types/index.js +1 -1
  54. package/lib/commonjs/types/index.js.map +1 -1
  55. package/lib/module/components/AddToWalletButton.js +1 -1
  56. package/lib/module/components/AddToWalletButton.js.map +1 -1
  57. package/lib/module/components/AddressSheet.js +1 -1
  58. package/lib/module/components/AddressSheet.js.map +1 -1
  59. package/lib/module/components/AuBECSDebitForm.js +1 -1
  60. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  61. package/lib/module/components/CardField.js +1 -1
  62. package/lib/module/components/CardField.js.map +1 -1
  63. package/lib/module/components/CardForm.js +1 -1
  64. package/lib/module/components/CardForm.js.map +1 -1
  65. package/lib/module/components/PlatformPayButton.js +1 -1
  66. package/lib/module/components/PlatformPayButton.js.map +1 -1
  67. package/lib/module/components/StripeContainer.js +1 -1
  68. package/lib/module/components/StripeContainer.js.map +1 -1
  69. package/lib/module/components/StripeProvider.js +1 -1
  70. package/lib/module/components/StripeProvider.js.map +1 -1
  71. package/lib/module/events.js +1 -1
  72. package/lib/module/events.js.map +1 -1
  73. package/lib/module/functions.js +1 -1
  74. package/lib/module/functions.js.map +1 -1
  75. package/lib/module/index.js +1 -1
  76. package/lib/module/index.js.map +1 -1
  77. package/lib/module/plugin/withStripe.js +1 -1
  78. package/lib/module/plugin/withStripe.js.map +1 -1
  79. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  80. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  81. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  82. package/lib/module/types/Errors.js +1 -1
  83. package/lib/module/types/Errors.js.map +1 -1
  84. package/lib/module/types/PlatformPay.js.map +1 -1
  85. package/lib/module/types/index.js +1 -1
  86. package/lib/module/types/index.js.map +1 -1
  87. package/lib/typescript/src/components/StripeProvider.d.ts.map +1 -1
  88. package/lib/typescript/src/events.d.ts +0 -3
  89. package/lib/typescript/src/events.d.ts.map +1 -1
  90. package/lib/typescript/src/functions.d.ts +1 -0
  91. package/lib/typescript/src/functions.d.ts.map +1 -1
  92. package/lib/typescript/src/index.d.ts +0 -1
  93. package/lib/typescript/src/index.d.ts.map +1 -1
  94. package/lib/typescript/src/plugin/withStripe.d.ts +0 -15
  95. package/lib/typescript/src/plugin/withStripe.d.ts.map +1 -1
  96. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +1 -0
  97. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  98. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +1 -0
  99. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  100. package/lib/typescript/src/types/Errors.d.ts +0 -5
  101. package/lib/typescript/src/types/Errors.d.ts.map +1 -1
  102. package/lib/typescript/src/types/PlatformPay.d.ts +7 -1
  103. package/lib/typescript/src/types/PlatformPay.d.ts.map +1 -1
  104. package/lib/typescript/src/types/index.d.ts +1 -7
  105. package/lib/typescript/src/types/index.d.ts.map +1 -1
  106. package/package.json +21 -2
  107. package/src/components/StripeProvider.tsx +0 -9
  108. package/src/events.ts +0 -22
  109. package/src/functions.ts +11 -0
  110. package/src/index.tsx +0 -1
  111. package/src/plugin/withStripe.ts +7 -104
  112. package/src/specs/NativeStripeSdkModule.ts +2 -0
  113. package/src/types/EmbeddedPaymentElement.tsx +7 -0
  114. package/src/types/Errors.ts +0 -6
  115. package/src/types/PlatformPay.ts +7 -1
  116. package/src/types/index.ts +0 -8
  117. package/stripe-react-native.podspec +8 -21
  118. package/.clang-format +0 -90
  119. package/.claude/settings.local.json +0 -11
  120. package/.editorconfig +0 -18
  121. package/.husky/pre-commit +0 -1
  122. package/.idea/GitLink.xml +0 -6
  123. package/.idea/codeStyles/Project.xml +0 -162
  124. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  125. package/.idea/misc.xml +0 -851
  126. package/.idea/modules.xml +0 -8
  127. package/.idea/stripe-react-native.iml +0 -9
  128. package/.idea/vcs.xml +0 -6
  129. package/.vscode/settings.json +0 -3
  130. package/CHANGELOG.md +0 -931
  131. package/CLAUDE.md +0 -148
  132. package/android/.gradle/8.11.1/checksums/checksums.lock +0 -0
  133. package/android/.gradle/8.11.1/executionHistory/executionHistory.bin +0 -0
  134. package/android/.gradle/8.11.1/executionHistory/executionHistory.lock +0 -0
  135. package/android/.gradle/8.11.1/fileChanges/last-build.bin +0 -0
  136. package/android/.gradle/8.11.1/fileHashes/fileHashes.bin +0 -0
  137. package/android/.gradle/8.11.1/fileHashes/fileHashes.lock +0 -0
  138. package/android/.gradle/8.11.1/gc.properties +0 -0
  139. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  140. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  141. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  142. package/android/.gradle/file-system.probe +0 -0
  143. package/android/.gradle/vcs-1/gc.properties +0 -0
  144. package/android/.idea/AndroidProjectSystem.xml +0 -6
  145. package/android/.idea/GitLink.xml +0 -6
  146. package/android/.idea/appInsightsSettings.xml +0 -23
  147. package/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt +0 -138
  148. package/android/src/oldarch/java/com/reactnativestripesdk/NativeOnrampSdkModuleSpec.java +0 -110
  149. package/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt +0 -844
  150. package/ios/StripeOnrampSdk.h +0 -17
  151. package/ios/StripeOnrampSdk.mm +0 -144
  152. package/lib/commonjs/hooks/useOnramp.js +0 -2
  153. package/lib/commonjs/hooks/useOnramp.js.map +0 -1
  154. package/lib/commonjs/specs/NativeOnrampSdkModule.js +0 -2
  155. package/lib/commonjs/specs/NativeOnrampSdkModule.js.map +0 -1
  156. package/lib/commonjs/types/Onramp.js +0 -2
  157. package/lib/commonjs/types/Onramp.js.map +0 -1
  158. package/lib/module/hooks/useOnramp.js +0 -2
  159. package/lib/module/hooks/useOnramp.js.map +0 -1
  160. package/lib/module/specs/NativeOnrampSdkModule.js +0 -2
  161. package/lib/module/specs/NativeOnrampSdkModule.js.map +0 -1
  162. package/lib/module/types/Onramp.js +0 -2
  163. package/lib/module/types/Onramp.js.map +0 -1
  164. package/lib/typescript/src/hooks/useOnramp.d.ts +0 -139
  165. package/lib/typescript/src/hooks/useOnramp.d.ts.map +0 -1
  166. package/lib/typescript/src/specs/NativeOnrampSdkModule.d.ts +0 -26
  167. package/lib/typescript/src/specs/NativeOnrampSdkModule.d.ts.map +0 -1
  168. package/lib/typescript/src/types/Onramp.d.ts +0 -259
  169. package/lib/typescript/src/types/Onramp.d.ts.map +0 -1
  170. package/package-lock.json +0 -14114
  171. package/patches/README.md +0 -55
  172. package/patches/old-arch-codegen-fix.patch +0 -91
  173. package/src/hooks/useOnramp.tsx +0 -297
  174. package/src/specs/NativeOnrampSdkModule.ts +0 -41
  175. package/src/types/Onramp.ts +0 -297
@@ -1,844 +0,0 @@
1
- package com.reactnativestripesdk
2
-
3
- import android.annotation.SuppressLint
4
- import android.app.Application
5
- import androidx.activity.ComponentActivity
6
- import androidx.compose.ui.graphics.Color
7
- import androidx.core.content.ContextCompat
8
- import androidx.fragment.app.FragmentActivity
9
- import androidx.lifecycle.SavedStateHandle
10
- import com.facebook.react.bridge.Arguments
11
- import com.facebook.react.bridge.Promise
12
- import com.facebook.react.bridge.ReactApplicationContext
13
- import com.facebook.react.bridge.ReactMethod
14
- import com.facebook.react.bridge.ReadableMap
15
- import com.facebook.react.bridge.WritableNativeMap
16
- import com.facebook.react.module.annotations.ReactModule
17
- import com.reactnativestripesdk.utils.ErrorType
18
- import com.reactnativestripesdk.utils.createCanceledError
19
- import com.reactnativestripesdk.utils.createEmptyResult
20
- import com.reactnativestripesdk.utils.createError
21
- import com.reactnativestripesdk.utils.createFailedError
22
- import com.reactnativestripesdk.utils.createMissingActivityError
23
- import com.reactnativestripesdk.utils.createMissingInitError
24
- import com.reactnativestripesdk.utils.createOnrampNotConfiguredError
25
- import com.reactnativestripesdk.utils.createResult
26
- import com.reactnativestripesdk.utils.getValOr
27
- import com.stripe.android.crypto.onramp.OnrampCoordinator
28
- import com.stripe.android.crypto.onramp.model.CryptoNetwork
29
- import com.stripe.android.crypto.onramp.model.DateOfBirth
30
- import com.stripe.android.crypto.onramp.model.KycInfo
31
- import com.stripe.android.crypto.onramp.model.LinkUserInfo
32
- import com.stripe.android.crypto.onramp.model.OnrampAttachKycInfoResult
33
- import com.stripe.android.crypto.onramp.model.OnrampAuthenticateResult
34
- import com.stripe.android.crypto.onramp.model.OnrampAuthorizeResult
35
- import com.stripe.android.crypto.onramp.model.OnrampCallbacks
36
- import com.stripe.android.crypto.onramp.model.OnrampCheckoutResult
37
- import com.stripe.android.crypto.onramp.model.OnrampCollectPaymentMethodResult
38
- import com.stripe.android.crypto.onramp.model.OnrampConfiguration
39
- import com.stripe.android.crypto.onramp.model.OnrampConfigurationResult
40
- import com.stripe.android.crypto.onramp.model.OnrampCreateCryptoPaymentTokenResult
41
- import com.stripe.android.crypto.onramp.model.OnrampHasLinkAccountResult
42
- import com.stripe.android.crypto.onramp.model.OnrampLogOutResult
43
- import com.stripe.android.crypto.onramp.model.OnrampRegisterLinkUserResult
44
- import com.stripe.android.crypto.onramp.model.OnrampRegisterWalletAddressResult
45
- import com.stripe.android.crypto.onramp.model.OnrampUpdatePhoneNumberResult
46
- import com.stripe.android.crypto.onramp.model.OnrampVerifyIdentityResult
47
- import com.stripe.android.crypto.onramp.model.PaymentMethodType
48
- import com.stripe.android.link.LinkAppearance
49
- import com.stripe.android.link.LinkAppearance.Colors
50
- import com.stripe.android.link.LinkAppearance.PrimaryButton
51
- import com.stripe.android.link.LinkAppearance.Style
52
- import com.stripe.android.link.LinkController.PaymentMethodPreview
53
- import com.stripe.android.link.PaymentMethodPreviewDetails
54
- import com.stripe.android.model.CardBrand
55
- import com.stripe.android.paymentsheet.PaymentSheet
56
- import kotlinx.coroutines.CompletableDeferred
57
- import kotlinx.coroutines.CoroutineScope
58
- import kotlinx.coroutines.Dispatchers
59
- import kotlinx.coroutines.launch
60
-
61
- @SuppressLint("RestrictedApi")
62
- @ReactModule(name = NativeOnrampSdkModuleSpec.NAME)
63
- class OnrampSdkModule(
64
- reactContext: ReactApplicationContext,
65
- ) : NativeOnrampSdkModuleSpec(reactContext) {
66
- private lateinit var publishableKey: String
67
- private var stripeAccountId: String? = null
68
-
69
- private var onrampCoordinator: OnrampCoordinator? = null
70
- private var onrampPresenter: OnrampCoordinator.Presenter? = null
71
-
72
- private var authenticateUserPromise: Promise? = null
73
- private var identityVerificationPromise: Promise? = null
74
- private var collectPaymentPromise: Promise? = null
75
- private var authorizePromise: Promise? = null
76
- private var checkoutPromise: Promise? = null
77
-
78
- private var checkoutClientSecretDeferred: CompletableDeferred<String>? = null
79
-
80
- @ReactMethod
81
- override fun initialise(
82
- params: ReadableMap,
83
- promise: Promise,
84
- ) {
85
- // Note: This method depends on `StripeSdkModule#initialise()` being called as well.
86
- val publishableKey = getValOr(params, "publishableKey", null) as String
87
- this.stripeAccountId = getValOr(params, "stripeAccountId", null)
88
- this.publishableKey = publishableKey
89
-
90
- promise.resolve(null)
91
- }
92
-
93
- /**
94
- * Safely get and cast the current activity as an AppCompatActivity. If that fails, the promise
95
- * provided will be resolved with an error message instructing the user to retry the method.
96
- */
97
- private fun getCurrentActivityOrResolveWithError(promise: Promise?): FragmentActivity? {
98
- (currentActivity as? FragmentActivity)?.let {
99
- return it
100
- }
101
- promise?.resolve(createMissingActivityError())
102
- return null
103
- }
104
-
105
- @ReactMethod
106
- override fun configureOnramp(
107
- config: ReadableMap,
108
- promise: Promise,
109
- ) {
110
- val application =
111
- currentActivity?.application ?: (reactApplicationContext.applicationContext as? Application)
112
- if (application == null) {
113
- promise.resolve(createMissingActivityError())
114
- return
115
- }
116
-
117
- val coordinator =
118
- onrampCoordinator ?: OnrampCoordinator
119
- .Builder()
120
- .build(application, SavedStateHandle())
121
- .also { this.onrampCoordinator = it }
122
-
123
- CoroutineScope(Dispatchers.IO).launch {
124
- val appearanceMap = config.getMap("appearance")
125
- val appearance =
126
- if (appearanceMap != null) {
127
- mapAppearance(appearanceMap)
128
- } else {
129
- LinkAppearance(style = Style.AUTOMATIC)
130
- }
131
-
132
- val displayName = config.getString("merchantDisplayName") ?: ""
133
-
134
- val cryptoCustomerId = config.getString("cryptoCustomerId")
135
-
136
- val configuration =
137
- OnrampConfiguration(
138
- merchantDisplayName = displayName,
139
- publishableKey = publishableKey,
140
- appearance = appearance,
141
- cryptoCustomerId = cryptoCustomerId,
142
- )
143
-
144
- val configureResult = coordinator.configure(configuration)
145
-
146
- CoroutineScope(Dispatchers.Main).launch {
147
- when (configureResult) {
148
- is OnrampConfigurationResult.Completed -> {
149
- createOnrampPresenter(promise)
150
- }
151
- is OnrampConfigurationResult.Failed -> {
152
- promise.resolve(createError(ErrorType.Failed.toString(), configureResult.error))
153
- }
154
- }
155
- }
156
- }
157
- }
158
-
159
- @ReactMethod
160
- private fun createOnrampPresenter(promise: Promise) {
161
- val activity = getCurrentActivityOrResolveWithError(promise) as? ComponentActivity
162
- if (activity == null) {
163
- promise.resolve(createMissingActivityError())
164
- return
165
- }
166
- if (onrampCoordinator == null) {
167
- promise.resolve(createMissingInitError())
168
- return
169
- }
170
- if (onrampPresenter != null) {
171
- promise.resolveVoid()
172
- return
173
- }
174
-
175
- val onrampCallbacks =
176
- OnrampCallbacks(
177
- authenticateUserCallback = { result ->
178
- handleOnrampAuthenticationResult(result, authenticateUserPromise!!)
179
- },
180
- verifyIdentityCallback = { result ->
181
- handleOnrampIdentityVerificationResult(result, identityVerificationPromise!!)
182
- },
183
- collectPaymentCallback = { result ->
184
- handleOnrampCollectPaymentResult(result, collectPaymentPromise!!)
185
- },
186
- authorizeCallback = { result ->
187
- handleOnrampAuthorizationResult(result, authorizePromise!!)
188
- },
189
- checkoutCallback = { result ->
190
- handleOnrampCheckoutResult(result, checkoutPromise!!)
191
- },
192
- )
193
-
194
- try {
195
- onrampPresenter = onrampCoordinator!!.createPresenter(activity, onrampCallbacks)
196
- promise.resolveVoid()
197
- } catch (e: Exception) {
198
- promise.resolve(createFailedError(e))
199
- }
200
- }
201
-
202
- @ReactMethod
203
- override fun hasLinkAccount(
204
- email: String,
205
- promise: Promise,
206
- ) {
207
- val coordinator =
208
- onrampCoordinator ?: run {
209
- promise.resolve(createOnrampNotConfiguredError())
210
- return
211
- }
212
- CoroutineScope(Dispatchers.IO).launch {
213
- when (val result = coordinator.hasLinkAccount(email)) {
214
- is OnrampHasLinkAccountResult.Completed -> {
215
- promise.resolveBoolean("hasLinkAccount", result.hasLinkAccount)
216
- }
217
- is OnrampHasLinkAccountResult.Failed -> {
218
- promise.resolve(createFailedError(result.error))
219
- }
220
- }
221
- }
222
- }
223
-
224
- @ReactMethod
225
- override fun registerLinkUser(
226
- info: ReadableMap,
227
- promise: Promise,
228
- ) {
229
- val coordinator =
230
- onrampCoordinator ?: run {
231
- promise.resolve(createOnrampNotConfiguredError())
232
- return
233
- }
234
- CoroutineScope(Dispatchers.IO).launch {
235
- val linkUserInfo =
236
- LinkUserInfo(
237
- email = info.getString("email") ?: "",
238
- phone = info.getString("phone") ?: "",
239
- country = info.getString("country") ?: "",
240
- fullName = info.getString("fullName"),
241
- )
242
-
243
- val result = coordinator.registerLinkUser(linkUserInfo)
244
- when (result) {
245
- is OnrampRegisterLinkUserResult.Completed -> {
246
- promise.resolveString("customerId", result.customerId)
247
- }
248
- is OnrampRegisterLinkUserResult.Failed -> {
249
- promise.resolve(createFailedError(result.error))
250
- }
251
- }
252
- }
253
- }
254
-
255
- @ReactMethod
256
- override fun registerWalletAddress(
257
- walletAddress: String,
258
- network: String,
259
- promise: Promise,
260
- ) {
261
- val coordinator =
262
- onrampCoordinator ?: run {
263
- promise.resolve(createOnrampNotConfiguredError())
264
- return
265
- }
266
- CoroutineScope(Dispatchers.IO).launch {
267
- val cryptoNetwork = enumValues<CryptoNetwork>().firstOrNull { it.value == network }
268
- if (cryptoNetwork == null) {
269
- promise.resolve(createError(ErrorType.Unknown.toString(), "Invalid network: $network"))
270
- return@launch
271
- }
272
-
273
- when (val result = coordinator.registerWalletAddress(walletAddress, cryptoNetwork)) {
274
- is OnrampRegisterWalletAddressResult.Completed -> {
275
- promise.resolveVoid()
276
- }
277
- is OnrampRegisterWalletAddressResult.Failed -> {
278
- promise.resolve(createFailedError(result.error))
279
- }
280
- }
281
- }
282
- }
283
-
284
- @ReactMethod
285
- override fun attachKycInfo(
286
- kycInfo: ReadableMap,
287
- promise: Promise,
288
- ) {
289
- val coordinator =
290
- onrampCoordinator ?: run {
291
- promise.resolve(createOnrampNotConfiguredError())
292
- return
293
- }
294
- CoroutineScope(Dispatchers.IO).launch {
295
- val firstName = kycInfo.getString("firstName")
296
- if (firstName.isNullOrEmpty()) {
297
- promise.resolve(
298
- createError(
299
- ErrorType.Unknown.toString(),
300
- "Missing required field: firstName",
301
- ),
302
- )
303
- return@launch
304
- }
305
- val lastName = kycInfo.getString("lastName")
306
- if (lastName.isNullOrEmpty()) {
307
- promise.resolve(
308
- createError(
309
- ErrorType.Unknown.toString(),
310
- "Missing required field: lastName",
311
- ),
312
- )
313
- return@launch
314
- }
315
- val idNumber = kycInfo.getString("idNumber")
316
- if (idNumber.isNullOrEmpty()) {
317
- promise.resolve(
318
- createError(
319
- ErrorType.Unknown.toString(),
320
- "Missing required field: idNumber",
321
- ),
322
- )
323
- return@launch
324
- }
325
-
326
- val dateOfBirthMap = kycInfo.getMap("dateOfBirth")
327
- val dob =
328
- if (
329
- dateOfBirthMap != null &&
330
- dateOfBirthMap.hasKey("day") &&
331
- dateOfBirthMap.hasKey("month") &&
332
- dateOfBirthMap.hasKey("year")
333
- ) {
334
- DateOfBirth(
335
- day = dateOfBirthMap.getInt("day"),
336
- month = dateOfBirthMap.getInt("month"),
337
- year = dateOfBirthMap.getInt("year"),
338
- )
339
- } else {
340
- promise.resolve(
341
- createError(
342
- ErrorType.Unknown.toString(),
343
- "Missing required field: dateOfBirth",
344
- ),
345
- )
346
- return@launch
347
- }
348
-
349
- val addressMap = kycInfo.getMap("address")
350
- val addressObj =
351
- addressMap?.let {
352
- PaymentSheet.Address(
353
- city = it.getString("city"),
354
- country = it.getString("country"),
355
- line1 = it.getString("line1"),
356
- line2 = it.getString("line2"),
357
- postalCode = it.getString("postalCode"),
358
- state = it.getString("state"),
359
- )
360
- } ?: PaymentSheet.Address()
361
-
362
- val kycInfoObj =
363
- KycInfo(
364
- firstName = firstName,
365
- lastName = lastName,
366
- idNumber = idNumber,
367
- dateOfBirth = dob,
368
- address = addressObj,
369
- )
370
-
371
- when (val result = coordinator.attachKycInfo(kycInfoObj)) {
372
- is OnrampAttachKycInfoResult.Completed -> {
373
- promise.resolveVoid()
374
- }
375
- is OnrampAttachKycInfoResult.Failed -> {
376
- promise.resolve(createFailedError(result.error))
377
- }
378
- }
379
- }
380
- }
381
-
382
- @ReactMethod
383
- override fun updatePhoneNumber(
384
- phone: String,
385
- promise: Promise,
386
- ) {
387
- val coordinator =
388
- onrampCoordinator ?: run {
389
- promise.resolve(createOnrampNotConfiguredError())
390
- return
391
- }
392
- CoroutineScope(Dispatchers.IO).launch {
393
- when (val result = coordinator.updatePhoneNumber(phone)) {
394
- OnrampUpdatePhoneNumberResult.Completed -> {
395
- promise.resolveVoid()
396
- }
397
- is OnrampUpdatePhoneNumberResult.Failed -> {
398
- promise.resolve(createFailedError(result.error))
399
- }
400
- }
401
- }
402
- }
403
-
404
- @ReactMethod
405
- override fun authenticateUser(promise: Promise) {
406
- val presenter =
407
- onrampPresenter ?: run {
408
- promise.resolve(createOnrampNotConfiguredError())
409
- return
410
- }
411
-
412
- authenticateUserPromise = promise
413
-
414
- presenter.authenticateUser()
415
- }
416
-
417
- @ReactMethod
418
- override fun verifyIdentity(promise: Promise) {
419
- val presenter =
420
- onrampPresenter ?: run {
421
- promise.resolve(createOnrampNotConfiguredError())
422
- return
423
- }
424
-
425
- identityVerificationPromise = promise
426
-
427
- presenter.verifyIdentity()
428
- }
429
-
430
- @ReactMethod
431
- override fun collectPaymentMethod(
432
- paymentMethod: String,
433
- platformPayParams: ReadableMap,
434
- promise: Promise,
435
- ) {
436
- val presenter =
437
- onrampPresenter ?: run {
438
- promise.resolve(createOnrampNotConfiguredError())
439
- return
440
- }
441
-
442
- val method =
443
- when (paymentMethod) {
444
- "Card" -> PaymentMethodType.Card
445
- "BankAccount" -> PaymentMethodType.BankAccount
446
- else -> {
447
- promise.resolve(
448
- createFailedError(
449
- IllegalArgumentException("Unsupported payment method: $paymentMethod"),
450
- ),
451
- )
452
- return
453
- }
454
- }
455
-
456
- collectPaymentPromise = promise
457
-
458
- presenter.collectPaymentMethod(method)
459
- }
460
-
461
- @ReactMethod
462
- override fun createCryptoPaymentToken(promise: Promise) {
463
- val coordinator =
464
- onrampCoordinator ?: run {
465
- promise.resolve(createOnrampNotConfiguredError())
466
- return
467
- }
468
-
469
- CoroutineScope(Dispatchers.IO).launch {
470
- val result = coordinator.createCryptoPaymentToken()
471
- CoroutineScope(Dispatchers.Main).launch {
472
- handleOnrampCreateCryptoPaymentTokenResult(result, promise)
473
- }
474
- }
475
- }
476
-
477
- @ReactMethod
478
- override fun performCheckout(
479
- onrampSessionId: String,
480
- promise: Promise,
481
- ) {
482
- val presenter =
483
- onrampPresenter ?: run {
484
- promise.resolve(createOnrampNotConfiguredError())
485
- return
486
- }
487
-
488
- val checkoutHandler: suspend () -> String = {
489
- checkoutClientSecretDeferred = CompletableDeferred()
490
-
491
- val params = Arguments.createMap()
492
- params.putString("onrampSessionId", onrampSessionId)
493
-
494
- emitOnCheckoutClientSecretRequested(params)
495
-
496
- checkoutClientSecretDeferred!!.await()
497
- }
498
-
499
- checkoutPromise = promise
500
-
501
- presenter.performCheckout(onrampSessionId, checkoutHandler)
502
- }
503
-
504
- @ReactMethod
505
- override fun provideCheckoutClientSecret(clientSecret: String?) {
506
- if (clientSecret != null) {
507
- checkoutClientSecretDeferred?.complete(clientSecret)
508
- } else {
509
- checkoutClientSecretDeferred?.completeExceptionally(
510
- RuntimeException("Failed to provide checkout client secret"),
511
- )
512
- }
513
- checkoutClientSecretDeferred = null
514
- }
515
-
516
- @ReactMethod
517
- override fun onrampAuthorize(
518
- linkAuthIntentId: String,
519
- promise: Promise,
520
- ) {
521
- val presenter =
522
- onrampPresenter ?: run {
523
- promise.resolve(createOnrampNotConfiguredError())
524
- return
525
- }
526
-
527
- authorizePromise = promise
528
-
529
- presenter.authorize(linkAuthIntentId)
530
- }
531
-
532
- @ReactMethod
533
- override fun getCryptoTokenDisplayData(
534
- token: ReadableMap,
535
- promise: Promise,
536
- ) {
537
- val context = reactApplicationContext
538
-
539
- val paymentDetails: PaymentMethodPreview? =
540
- when {
541
- token.hasKey("card") -> {
542
- val cardMap = token.getMap("card")
543
- if (cardMap != null) {
544
- val brand = cardMap.getString("brand") ?: ""
545
- val funding = cardMap.getString("funding") ?: ""
546
- val last4 = cardMap.getString("last4") ?: ""
547
- val cardBrand = CardBrand.fromCode(brand)
548
-
549
- PaymentMethodPreview.create(
550
- context = context,
551
- details =
552
- PaymentMethodPreviewDetails.Card(
553
- brand = cardBrand,
554
- funding = funding,
555
- last4 = last4,
556
- ),
557
- )
558
- } else {
559
- null
560
- }
561
- }
562
- token.hasKey("us_bank_account") -> {
563
- val bankMap = token.getMap("us_bank_account")
564
- if (bankMap != null) {
565
- val bankName = bankMap.getString("bank_name")
566
- val last4 = bankMap.getString("last4") ?: ""
567
- PaymentMethodPreview.create(
568
- context = context,
569
- details =
570
- PaymentMethodPreviewDetails.BankAccount(
571
- bankIconCode = null,
572
- bankName = bankName,
573
- last4 = last4,
574
- ),
575
- )
576
- } else {
577
- null
578
- }
579
- }
580
- else -> null
581
- }
582
-
583
- if (paymentDetails == null) {
584
- promise.resolve(
585
- createFailedError(
586
- IllegalArgumentException("Unsupported payment method"),
587
- ),
588
- )
589
- return
590
- }
591
-
592
- val icon =
593
- currentActivity
594
- ?.let { ContextCompat.getDrawable(it, paymentDetails.iconRes) }
595
- ?.let { "data:image/png;base64," + getBase64FromBitmap(getBitmapFromDrawable(it)) }
596
-
597
- val displayData = Arguments.createMap()
598
-
599
- displayData.putString("icon", icon)
600
- displayData.putString("label", paymentDetails.label)
601
- displayData.putString("sublabel", paymentDetails.sublabel)
602
-
603
- promise.resolve(createResult("displayData", displayData))
604
- }
605
-
606
- @ReactMethod
607
- override fun logout(promise: Promise) {
608
- val coordinator =
609
- onrampCoordinator ?: run {
610
- promise.resolve(createOnrampNotConfiguredError())
611
- return
612
- }
613
-
614
- CoroutineScope(Dispatchers.IO).launch {
615
- val result = coordinator.logOut()
616
- CoroutineScope(Dispatchers.Main).launch {
617
- handleLogOutResult(result, promise)
618
- }
619
- }
620
- }
621
-
622
- private fun mapAppearance(appearanceMap: ReadableMap): LinkAppearance {
623
- val lightColorsMap = appearanceMap.getMap("lightColors")
624
- val darkColorsMap = appearanceMap.getMap("darkColors")
625
- val styleStr = appearanceMap.getString("style")
626
- val primaryButtonMap = appearanceMap.getMap("primaryButton")
627
-
628
- val lightColors =
629
- if (lightColorsMap != null) {
630
- val primaryColorStr = lightColorsMap.getString("primary")
631
- val contentColorStr = lightColorsMap.getString("contentOnPrimary")
632
- val borderSelectedColorStr = lightColorsMap.getString("borderSelected")
633
-
634
- Colors(
635
- primary = Color(android.graphics.Color.parseColor(primaryColorStr)),
636
- contentOnPrimary = Color(android.graphics.Color.parseColor(contentColorStr)),
637
- borderSelected = Color(android.graphics.Color.parseColor(borderSelectedColorStr)),
638
- )
639
- } else {
640
- null
641
- }
642
-
643
- val darkColors =
644
- if (darkColorsMap != null) {
645
- val primaryColorStr = darkColorsMap.getString("primary")
646
- val contentColorStr = darkColorsMap.getString("contentOnPrimary")
647
- val borderSelectedColorStr = darkColorsMap.getString("borderSelected")
648
-
649
- Colors(
650
- primary = Color(android.graphics.Color.parseColor(primaryColorStr)),
651
- contentOnPrimary = Color(android.graphics.Color.parseColor(contentColorStr)),
652
- borderSelected = Color(android.graphics.Color.parseColor(borderSelectedColorStr)),
653
- )
654
- } else {
655
- null
656
- }
657
-
658
- val style =
659
- when (styleStr) {
660
- "ALWAYS_LIGHT" -> Style.ALWAYS_LIGHT
661
- "ALWAYS_DARK" -> Style.ALWAYS_DARK
662
- else -> Style.AUTOMATIC
663
- }
664
-
665
- val primaryButton =
666
- if (primaryButtonMap != null) {
667
- PrimaryButton(
668
- cornerRadiusDp =
669
- if (primaryButtonMap.hasKey("cornerRadius")) {
670
- primaryButtonMap.getDouble("cornerRadius").toFloat()
671
- } else {
672
- null
673
- },
674
- heightDp =
675
- if (primaryButtonMap.hasKey("height")) {
676
- primaryButtonMap.getDouble("height").toFloat()
677
- } else {
678
- null
679
- },
680
- )
681
- } else {
682
- null
683
- }
684
-
685
- val default = LinkAppearance(style = Style.AUTOMATIC)
686
- return LinkAppearance(
687
- lightColors = lightColors ?: default.lightColors,
688
- darkColors = darkColors ?: default.darkColors,
689
- style = style,
690
- primaryButton = primaryButton ?: default.primaryButton,
691
- )
692
- }
693
-
694
- private fun handleOnrampAuthenticationResult(
695
- result: OnrampAuthenticateResult,
696
- promise: Promise,
697
- ) {
698
- when (result) {
699
- is OnrampAuthenticateResult.Completed -> {
700
- promise.resolveString("customerId", result.customerId)
701
- }
702
- is OnrampAuthenticateResult.Cancelled -> {
703
- promise.resolve(createCanceledError("Authentication was cancelled"))
704
- }
705
- is OnrampAuthenticateResult.Failed -> {
706
- promise.resolve(createFailedError(result.error))
707
- }
708
- }
709
- }
710
-
711
- private fun handleOnrampIdentityVerificationResult(
712
- result: OnrampVerifyIdentityResult,
713
- promise: Promise,
714
- ) {
715
- when (result) {
716
- is OnrampVerifyIdentityResult.Completed -> {
717
- promise.resolveVoid()
718
- }
719
- is OnrampVerifyIdentityResult.Cancelled -> {
720
- promise.resolve(createCanceledError("Identity verification was cancelled"))
721
- }
722
- is OnrampVerifyIdentityResult.Failed -> {
723
- promise.resolve(createFailedError(result.error))
724
- }
725
- }
726
- }
727
-
728
- private fun handleOnrampCollectPaymentResult(
729
- result: OnrampCollectPaymentMethodResult,
730
- promise: Promise,
731
- ) {
732
- when (result) {
733
- is OnrampCollectPaymentMethodResult.Completed -> {
734
- val displayData = Arguments.createMap()
735
- val icon =
736
- currentActivity
737
- ?.let { ContextCompat.getDrawable(it, result.displayData.iconRes) }
738
- ?.let { "data:image/png;base64," + getBase64FromBitmap(getBitmapFromDrawable(it)) }
739
- displayData.putString("icon", icon)
740
- displayData.putString("label", result.displayData.label)
741
- result.displayData.sublabel?.let { displayData.putString("sublabel", it) }
742
- promise.resolve(createResult("displayData", displayData))
743
- }
744
- is OnrampCollectPaymentMethodResult.Cancelled -> {
745
- promise.resolve(createCanceledError("Payment collection was cancelled"))
746
- }
747
- is OnrampCollectPaymentMethodResult.Failed -> {
748
- promise.resolve(createFailedError(result.error))
749
- }
750
- }
751
- }
752
-
753
- private fun handleOnrampAuthorizationResult(
754
- result: OnrampAuthorizeResult,
755
- promise: Promise,
756
- ) {
757
- when (result) {
758
- is OnrampAuthorizeResult.Consented -> {
759
- promise.resolve(
760
- WritableNativeMap().apply {
761
- putString("status", "Consented")
762
- putString("customerId", result.customerId)
763
- },
764
- )
765
- }
766
- is OnrampAuthorizeResult.Denied -> {
767
- promise.resolve(
768
- WritableNativeMap().apply {
769
- putString("status", "Denied")
770
- },
771
- )
772
- }
773
- is OnrampAuthorizeResult.Canceled -> {
774
- promise.resolve(createCanceledError("Authorization was cancelled"))
775
- }
776
- is OnrampAuthorizeResult.Failed -> {
777
- promise.resolve(createFailedError(result.error))
778
- }
779
- }
780
- }
781
-
782
- private fun handleOnrampCheckoutResult(
783
- result: OnrampCheckoutResult,
784
- promise: Promise,
785
- ) {
786
- when (result) {
787
- is OnrampCheckoutResult.Completed -> {
788
- promise.resolveVoid()
789
- }
790
- is OnrampCheckoutResult.Canceled -> {
791
- promise.resolve(createCanceledError("Checkout was cancelled"))
792
- }
793
- is OnrampCheckoutResult.Failed -> {
794
- promise.resolve(createFailedError(result.error))
795
- }
796
- }
797
- }
798
-
799
- private fun handleOnrampCreateCryptoPaymentTokenResult(
800
- result: OnrampCreateCryptoPaymentTokenResult,
801
- promise: Promise,
802
- ) {
803
- when (result) {
804
- is OnrampCreateCryptoPaymentTokenResult.Completed -> {
805
- promise.resolveString("cryptoPaymentToken", result.cryptoPaymentToken)
806
- }
807
- is OnrampCreateCryptoPaymentTokenResult.Failed -> {
808
- promise.resolve(createFailedError(result.error))
809
- }
810
- }
811
- }
812
-
813
- private fun handleLogOutResult(
814
- result: OnrampLogOutResult,
815
- promise: Promise,
816
- ) {
817
- when (result) {
818
- is OnrampLogOutResult.Completed -> {
819
- promise.resolveVoid()
820
- }
821
- is OnrampLogOutResult.Failed -> {
822
- promise.resolve(createFailedError(result.error))
823
- }
824
- }
825
- }
826
-
827
- private fun Promise.resolveVoid() {
828
- resolve(createEmptyResult())
829
- }
830
-
831
- private fun Promise.resolveString(
832
- key: String,
833
- value: String,
834
- ) {
835
- resolve(WritableNativeMap().apply { putString(key, value) })
836
- }
837
-
838
- private fun Promise.resolveBoolean(
839
- key: String,
840
- value: Boolean,
841
- ) {
842
- resolve(WritableNativeMap().apply { putBoolean(key, value) })
843
- }
844
- }