@stripe/stripe-react-native 0.69.0 → 0.70.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.
- package/android/.idea/AndroidProjectSystem.xml +6 -0
- package/android/.idea/caches/deviceStreaming.xml +835 -0
- package/android/.idea/compiler.xml +6 -0
- package/android/.idea/gradle.xml +17 -0
- package/android/.idea/migrations.xml +10 -0
- package/android/.idea/misc.xml +10 -0
- package/android/.idea/runConfigurations.xml +17 -0
- package/android/.idea/vcs.xml +6 -0
- package/android/local.properties +8 -0
- package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +7 -8
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeOnrampSdkModuleSpec.java +8 -0
- package/android/src/onramp/java/com/reactnativestripesdk/OnrampErrors.kt +22 -8
- package/android/src/onramp/java/com/reactnativestripesdk/OnrampMappers.kt +48 -0
- package/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt +62 -0
- package/android/src/test/java/com/reactnativestripesdk/OnrampErrorsTest.kt +103 -26
- package/android/src/test/java/com/reactnativestripesdk/mappers/OnrampMappersTest.kt +37 -0
- package/android/src/test/java/com/reactnativestripesdk/mappers/PaymentMethodMappersTest.kt +110 -0
- package/ios/Mappers.swift +19 -0
- package/ios/OnrampErrors.swift +23 -8
- package/ios/StripeOnrampSdk.mm +16 -0
- package/ios/StripeSdkImpl.swift +56 -0
- package/jest/setup.js +2 -0
- package/lib/commonjs/components/AddToWalletButton.js +1 -1
- package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
- package/lib/commonjs/components/AddressSheet.js +1 -1
- package/lib/commonjs/components/AddressSheet.js.map +1 -1
- package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
- package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
- package/lib/commonjs/components/CardField.js +1 -1
- package/lib/commonjs/components/CardField.js.map +1 -1
- package/lib/commonjs/components/CardForm.js +1 -1
- package/lib/commonjs/components/CardForm.js.map +1 -1
- package/lib/commonjs/components/CurrencySelectorElement.js +1 -1
- package/lib/commonjs/components/CurrencySelectorElement.js.map +1 -1
- package/lib/commonjs/components/PaymentMethodMessagingElement.js +1 -1
- package/lib/commonjs/components/PaymentMethodMessagingElement.js.map +1 -1
- package/lib/commonjs/components/PlatformPayButton.js +1 -1
- package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
- package/lib/commonjs/components/StripeContainer.js +1 -1
- package/lib/commonjs/components/StripeContainer.js.map +1 -1
- package/lib/commonjs/components/StripeProvider.js +1 -1
- package/lib/commonjs/components/StripeProvider.js.map +1 -1
- package/lib/commonjs/connect/Components.js +1 -1
- package/lib/commonjs/connect/Components.js.map +1 -1
- package/lib/commonjs/connect/ConnectComponentsProvider.js +1 -1
- package/lib/commonjs/connect/ConnectComponentsProvider.js.map +1 -1
- package/lib/commonjs/connect/EmbeddedComponent.js +1 -1
- package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
- package/lib/commonjs/connect/ModalCloseButton.js +1 -1
- package/lib/commonjs/connect/ModalCloseButton.js.map +1 -1
- package/lib/commonjs/connect/NavigationBar.js +1 -1
- package/lib/commonjs/connect/NavigationBar.js.map +1 -1
- package/lib/commonjs/helpers.js +1 -1
- package/lib/commonjs/hooks/useOnramp.js +1 -1
- package/lib/commonjs/hooks/useOnramp.js.map +1 -1
- package/lib/commonjs/specs/NativeAddToWalletButton.js +1 -1
- package/lib/commonjs/specs/NativeAddressSheet.js +1 -1
- package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
- package/lib/commonjs/specs/NativeAuBECSDebitForm.js +1 -1
- package/lib/commonjs/specs/NativeCardField.js +1 -1
- package/lib/commonjs/specs/NativeCardField.js.map +1 -1
- package/lib/commonjs/specs/NativeCardForm.js +1 -1
- package/lib/commonjs/specs/NativeCardForm.js.map +1 -1
- package/lib/commonjs/specs/NativeConnectAccountOnboardingView.js +1 -1
- package/lib/commonjs/specs/NativeCurrencySelectorElement.js +1 -1
- package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +1 -1
- package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js.map +1 -1
- package/lib/commonjs/specs/NativeGooglePayButton.js +1 -1
- package/lib/commonjs/specs/NativeNavigationBar.js +1 -1
- package/lib/commonjs/specs/NativeOnrampSdkModule.js.map +1 -1
- package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js +1 -1
- package/lib/commonjs/specs/NativeStripeContainer.js +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/commonjs/types/Onramp.js +1 -1
- package/lib/commonjs/types/Onramp.js.map +1 -1
- package/lib/module/components/AddToWalletButton.js +1 -1
- package/lib/module/components/AddToWalletButton.js.map +1 -1
- package/lib/module/components/AddressSheet.js +1 -1
- package/lib/module/components/AddressSheet.js.map +1 -1
- package/lib/module/components/AuBECSDebitForm.js +1 -1
- package/lib/module/components/AuBECSDebitForm.js.map +1 -1
- package/lib/module/components/CardField.js +1 -1
- package/lib/module/components/CardField.js.map +1 -1
- package/lib/module/components/CardForm.js +1 -1
- package/lib/module/components/CardForm.js.map +1 -1
- package/lib/module/components/CurrencySelectorElement.js +1 -1
- package/lib/module/components/CurrencySelectorElement.js.map +1 -1
- package/lib/module/components/PaymentMethodMessagingElement.js +1 -1
- package/lib/module/components/PaymentMethodMessagingElement.js.map +1 -1
- package/lib/module/components/PlatformPayButton.js +1 -1
- package/lib/module/components/PlatformPayButton.js.map +1 -1
- package/lib/module/components/StripeContainer.js +1 -1
- package/lib/module/components/StripeContainer.js.map +1 -1
- package/lib/module/components/StripeProvider.js +1 -1
- package/lib/module/components/StripeProvider.js.map +1 -1
- package/lib/module/connect/Components.js +1 -1
- package/lib/module/connect/Components.js.map +1 -1
- package/lib/module/connect/ConnectComponentsProvider.js +1 -1
- package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
- package/lib/module/connect/EmbeddedComponent.js +1 -1
- package/lib/module/connect/EmbeddedComponent.js.map +1 -1
- package/lib/module/connect/ModalCloseButton.js +1 -1
- package/lib/module/connect/ModalCloseButton.js.map +1 -1
- package/lib/module/connect/NavigationBar.js +1 -1
- package/lib/module/connect/NavigationBar.js.map +1 -1
- package/lib/module/helpers.js +1 -1
- package/lib/module/hooks/useOnramp.js +1 -1
- package/lib/module/hooks/useOnramp.js.map +1 -1
- package/lib/module/specs/NativeAddToWalletButton.js +1 -1
- package/lib/module/specs/NativeAddressSheet.js +1 -1
- package/lib/module/specs/NativeApplePayButton.js +1 -1
- package/lib/module/specs/NativeAuBECSDebitForm.js +1 -1
- package/lib/module/specs/NativeCardField.js +1 -1
- package/lib/module/specs/NativeCardField.js.map +1 -1
- package/lib/module/specs/NativeCardForm.js +1 -1
- package/lib/module/specs/NativeCardForm.js.map +1 -1
- package/lib/module/specs/NativeConnectAccountOnboardingView.js +1 -1
- package/lib/module/specs/NativeCurrencySelectorElement.js +1 -1
- package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
- package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -1
- package/lib/module/specs/NativeGooglePayButton.js +1 -1
- package/lib/module/specs/NativeNavigationBar.js +1 -1
- package/lib/module/specs/NativeOnrampSdkModule.js.map +1 -1
- package/lib/module/specs/NativePaymentMethodMessagingElement.js +1 -1
- package/lib/module/specs/NativeStripeContainer.js +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/module/types/Onramp.js +1 -1
- package/lib/module/types/Onramp.js.map +1 -1
- package/lib/typescript/src/components/StripeProvider.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useOnramp.d.ts +18 -0
- package/lib/typescript/src/hooks/useOnramp.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeOnrampSdkModule.d.ts +2 -0
- package/lib/typescript/src/specs/NativeOnrampSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/types/Onramp.d.ts +84 -10
- package/lib/typescript/src/types/Onramp.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/StripeProvider.tsx +0 -2
- package/src/hooks/useOnramp.tsx +50 -83
- package/src/specs/NativeOnrampSdkModule.ts +8 -0
- package/src/types/Onramp.ts +100 -9
- package/lib/commonjs/internal/stripeConfig.js +0 -2
- package/lib/commonjs/internal/stripeConfig.js.map +0 -1
- package/lib/module/internal/stripeConfig.js +0 -2
- package/lib/module/internal/stripeConfig.js.map +0 -1
- package/lib/typescript/src/internal/stripeConfig.d.ts +0 -3
- package/lib/typescript/src/internal/stripeConfig.d.ts.map +0 -1
- package/src/internal/stripeConfig.ts +0 -9
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="GradleSettings">
|
|
4
|
+
<option name="linkedExternalProjectsSettings">
|
|
5
|
+
<GradleProjectSettings>
|
|
6
|
+
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
|
7
|
+
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
8
|
+
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
|
9
|
+
<option name="modules">
|
|
10
|
+
<set>
|
|
11
|
+
<option value="$PROJECT_DIR$" />
|
|
12
|
+
</set>
|
|
13
|
+
</option>
|
|
14
|
+
</GradleProjectSettings>
|
|
15
|
+
</option>
|
|
16
|
+
</component>
|
|
17
|
+
</project>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
4
|
+
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
|
5
|
+
<output url="file://$PROJECT_DIR$/build/classes" />
|
|
6
|
+
</component>
|
|
7
|
+
<component name="ProjectType">
|
|
8
|
+
<option name="id" value="Android" />
|
|
9
|
+
</component>
|
|
10
|
+
</project>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="RunConfigurationProducerService">
|
|
4
|
+
<option name="ignoredProducers">
|
|
5
|
+
<set>
|
|
6
|
+
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
|
7
|
+
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
|
8
|
+
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
|
9
|
+
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
|
10
|
+
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
|
11
|
+
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
|
12
|
+
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
|
13
|
+
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
|
14
|
+
</set>
|
|
15
|
+
</option>
|
|
16
|
+
</component>
|
|
17
|
+
</project>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
## This file must *NOT* be checked into Version Control Systems,
|
|
2
|
+
# as it contains information specific to your local configuration.
|
|
3
|
+
#
|
|
4
|
+
# Location of the SDK. This is only used by Gradle.
|
|
5
|
+
# For customization when using a Version Control System, please read the
|
|
6
|
+
# header note.
|
|
7
|
+
#Tue Jul 29 21:50:46 PDT 2025
|
|
8
|
+
sdk.dir=/Users/cttsai/Library/Android/sdk
|
|
@@ -360,6 +360,11 @@ internal fun mapFromToken(token: Token): WritableMap {
|
|
|
360
360
|
return tokenMap
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
+
private fun mapFromStringList(list: Collection<String>?): WritableArray? =
|
|
364
|
+
list?.let { networks ->
|
|
365
|
+
Arguments.createArray().also { arr -> networks.forEach { arr.pushString(it) } }
|
|
366
|
+
}
|
|
367
|
+
|
|
363
368
|
internal fun mapFromPaymentMethod(paymentMethod: PaymentMethod): WritableMap {
|
|
364
369
|
val pm: WritableMap = Arguments.createMap()
|
|
365
370
|
|
|
@@ -379,13 +384,7 @@ internal fun mapFromPaymentMethod(paymentMethod: PaymentMethod): WritableMap {
|
|
|
379
384
|
it.putString("last4", paymentMethod.card?.last4)
|
|
380
385
|
it.putString("fingerprint", paymentMethod.card?.fingerprint)
|
|
381
386
|
it.putString("preferredNetwork", paymentMethod.card?.networks?.preferred)
|
|
382
|
-
it.putArray(
|
|
383
|
-
"availableNetworks",
|
|
384
|
-
paymentMethod.card
|
|
385
|
-
?.networks
|
|
386
|
-
?.available
|
|
387
|
-
?.toList() as? ReadableArray,
|
|
388
|
-
)
|
|
387
|
+
it.putArray("availableNetworks", mapFromStringList(paymentMethod.card?.networks?.available))
|
|
389
388
|
it.putMap(
|
|
390
389
|
"threeDSecureUsage",
|
|
391
390
|
Arguments.createMap().also { threeDSecureUsageMap ->
|
|
@@ -455,7 +454,7 @@ internal fun mapFromPaymentMethod(paymentMethod: PaymentMethod): WritableMap {
|
|
|
455
454
|
it.putString("preferredNetworks", paymentMethod.usBankAccount?.networks?.preferred)
|
|
456
455
|
it.putArray(
|
|
457
456
|
"supportedNetworks",
|
|
458
|
-
paymentMethod.usBankAccount?.networks?.supported
|
|
457
|
+
mapFromStringList(paymentMethod.usBankAccount?.networks?.supported),
|
|
459
458
|
)
|
|
460
459
|
},
|
|
461
460
|
)
|
|
@@ -55,6 +55,14 @@ public abstract class NativeOnrampSdkModuleSpec extends ReactContextBaseJavaModu
|
|
|
55
55
|
@DoNotStrip
|
|
56
56
|
public abstract void registerWalletAddress(String walletAddress, String network, Promise promise);
|
|
57
57
|
|
|
58
|
+
@ReactMethod
|
|
59
|
+
@DoNotStrip
|
|
60
|
+
public abstract void getWalletOwnershipChallenge(String walletAddress, String network, Promise promise);
|
|
61
|
+
|
|
62
|
+
@ReactMethod
|
|
63
|
+
@DoNotStrip
|
|
64
|
+
public abstract void submitWalletOwnershipSignature(String challengeId, String signature, Promise promise);
|
|
65
|
+
|
|
58
66
|
@ReactMethod
|
|
59
67
|
@DoNotStrip
|
|
60
68
|
public abstract void attachKycInfo(ReadableMap kycInfo, Promise promise);
|
|
@@ -7,7 +7,6 @@ import com.facebook.react.bridge.WritableMap
|
|
|
7
7
|
import com.reactnativestripesdk.utils.ErrorType
|
|
8
8
|
import com.stripe.android.core.exception.StripeException
|
|
9
9
|
import com.stripe.android.crypto.onramp.ExperimentalCryptoOnramp
|
|
10
|
-
import com.stripe.android.crypto.onramp.exception.AppAttestationException
|
|
11
10
|
import com.stripe.android.crypto.onramp.exception.CryptoOnrampApiException
|
|
12
11
|
import com.stripe.android.crypto.onramp.exception.StripeCryptoOnrampError
|
|
13
12
|
|
|
@@ -40,16 +39,13 @@ private fun createOnrampError(
|
|
|
40
39
|
type = apiErrorContext.apiErrorType ?: stripeError?.type,
|
|
41
40
|
stripeErrorCode = apiException.code,
|
|
42
41
|
) {
|
|
43
|
-
|
|
44
|
-
putString("developerMessage", apiException.developerMessage)
|
|
45
|
-
putString("userMessage", apiException.userMessage)
|
|
42
|
+
putCommonOnrampFields(apiException, onrampErrorType)
|
|
46
43
|
putString("reason", apiErrorContext.reason)
|
|
47
44
|
putString("requestId", apiErrorContext.requestId)
|
|
48
45
|
putString("apiErrorCode", apiErrorContext.apiErrorCode)
|
|
49
46
|
putString("apiErrorType", apiErrorContext.apiErrorType)
|
|
50
47
|
putString("apiErrorMessage", apiErrorContext.apiErrorMessage)
|
|
51
48
|
putString("apiUserMessage", apiErrorContext.apiUserMessage)
|
|
52
|
-
putString("docUrl", apiErrorContext.docUrl)
|
|
53
49
|
}
|
|
54
50
|
}
|
|
55
51
|
|
|
@@ -67,11 +63,22 @@ private fun createNonApiOnrampError(
|
|
|
67
63
|
localizedMessage = error.localizedMessage,
|
|
68
64
|
stripeErrorCode = onrampError.code,
|
|
69
65
|
) {
|
|
70
|
-
|
|
71
|
-
putString("userMessage", onrampError.userMessage)
|
|
66
|
+
putCommonOnrampFields(onrampError, onrampError.toOnrampErrorType())
|
|
72
67
|
}
|
|
73
68
|
}
|
|
74
69
|
|
|
70
|
+
private fun WritableMap.putCommonOnrampFields(
|
|
71
|
+
error: StripeCryptoOnrampError,
|
|
72
|
+
onrampErrorType: String? = null,
|
|
73
|
+
) {
|
|
74
|
+
onrampErrorType?.let {
|
|
75
|
+
putString("onrampErrorType", it)
|
|
76
|
+
}
|
|
77
|
+
putString("developerMessage", error.developerMessage)
|
|
78
|
+
putString("userMessage", error.userMessage)
|
|
79
|
+
putString("docUrl", error.docUrl)
|
|
80
|
+
}
|
|
81
|
+
|
|
75
82
|
private fun createOnrampMessageError(
|
|
76
83
|
code: String,
|
|
77
84
|
message: String?,
|
|
@@ -79,12 +86,19 @@ private fun createOnrampMessageError(
|
|
|
79
86
|
createOnrampErrorMap(code = code, message = message)
|
|
80
87
|
|
|
81
88
|
private fun CryptoOnrampApiException.toOnrampErrorType(): String =
|
|
82
|
-
if (
|
|
89
|
+
if (code == "link_failed_to_attest_request") {
|
|
83
90
|
"AppAttestationError"
|
|
84
91
|
} else {
|
|
85
92
|
"UncategorizedApiError"
|
|
86
93
|
}
|
|
87
94
|
|
|
95
|
+
private fun StripeCryptoOnrampError.toOnrampErrorType(): String? =
|
|
96
|
+
if (code == "app_attestation_unavailable") {
|
|
97
|
+
"AppAttestationUnavailableError"
|
|
98
|
+
} else {
|
|
99
|
+
null
|
|
100
|
+
}
|
|
101
|
+
|
|
88
102
|
private fun createGenericError(
|
|
89
103
|
code: String,
|
|
90
104
|
error: Throwable,
|
|
@@ -10,10 +10,13 @@ import com.facebook.react.bridge.ReadableMap
|
|
|
10
10
|
import com.facebook.react.bridge.WritableArray
|
|
11
11
|
import com.stripe.android.core.model.CountryCode
|
|
12
12
|
import com.stripe.android.crypto.onramp.ExperimentalCryptoOnramp
|
|
13
|
+
import com.stripe.android.crypto.onramp.model.CryptoConsumerWallet
|
|
14
|
+
import com.stripe.android.crypto.onramp.model.CryptoNetwork
|
|
13
15
|
import com.stripe.android.crypto.onramp.exception.SDKVersion
|
|
14
16
|
import com.stripe.android.crypto.onramp.model.KycInfo
|
|
15
17
|
import com.stripe.android.crypto.onramp.model.OnrampConfiguration
|
|
16
18
|
import com.stripe.android.crypto.onramp.model.PaymentMethodDisplayData
|
|
19
|
+
import com.stripe.android.crypto.onramp.model.WalletOwnershipChallenge
|
|
17
20
|
import com.stripe.android.crypto.onramp.model.compliance.ComplianceIdentifier
|
|
18
21
|
import com.stripe.android.crypto.onramp.model.compliance.ComplianceIdentifierAlternativeGroup
|
|
19
22
|
import com.stripe.android.crypto.onramp.model.compliance.ComplianceIdentifierRequirement
|
|
@@ -203,6 +206,51 @@ internal fun mapFromKycInfo(kycInfo: KycInfo): ReadableMap {
|
|
|
203
206
|
return result
|
|
204
207
|
}
|
|
205
208
|
|
|
209
|
+
internal fun mapFromWalletOwnershipChallenge(challenge: WalletOwnershipChallenge) =
|
|
210
|
+
mapFromWalletOwnershipChallenge(
|
|
211
|
+
challengeId = challenge.challengeId,
|
|
212
|
+
walletAddress = challenge.walletAddress,
|
|
213
|
+
network = challenge.network,
|
|
214
|
+
message = challenge.message,
|
|
215
|
+
expiresAt = challenge.expiresAt,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
internal fun mapFromWalletOwnershipChallenge(
|
|
219
|
+
challengeId: String,
|
|
220
|
+
walletAddress: String,
|
|
221
|
+
network: CryptoNetwork,
|
|
222
|
+
message: String,
|
|
223
|
+
expiresAt: String,
|
|
224
|
+
) =
|
|
225
|
+
Arguments.createMap().apply {
|
|
226
|
+
putString("challengeId", challengeId)
|
|
227
|
+
putString("walletAddress", walletAddress)
|
|
228
|
+
putString("network", network.value)
|
|
229
|
+
putString("message", message)
|
|
230
|
+
putString("expiresAt", expiresAt)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
internal fun mapFromCryptoConsumerWallet(wallet: CryptoConsumerWallet) =
|
|
234
|
+
mapFromCryptoConsumerWallet(
|
|
235
|
+
id = wallet.id,
|
|
236
|
+
network = wallet.network,
|
|
237
|
+
walletAddress = wallet.walletAddress,
|
|
238
|
+
verifiedOwnership = wallet.verifiedOwnership,
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
internal fun mapFromCryptoConsumerWallet(
|
|
242
|
+
id: String,
|
|
243
|
+
network: CryptoNetwork,
|
|
244
|
+
walletAddress: String,
|
|
245
|
+
verifiedOwnership: Boolean,
|
|
246
|
+
) =
|
|
247
|
+
Arguments.createMap().apply {
|
|
248
|
+
putString("id", id)
|
|
249
|
+
putString("walletAddress", walletAddress)
|
|
250
|
+
putString("network", network.value)
|
|
251
|
+
putBoolean("verifiedOwnership", verifiedOwnership)
|
|
252
|
+
}
|
|
253
|
+
|
|
206
254
|
internal fun mapToComplianceIdentifiers(identifiers: ReadableArray): List<ComplianceIdentifier> {
|
|
207
255
|
val complianceIdentifiers = mutableListOf<ComplianceIdentifier>()
|
|
208
256
|
|
|
@@ -39,6 +39,7 @@ import com.stripe.android.crypto.onramp.model.OnrampCheckoutResult
|
|
|
39
39
|
import com.stripe.android.crypto.onramp.model.OnrampCollectPaymentMethodResult
|
|
40
40
|
import com.stripe.android.crypto.onramp.model.OnrampConfigurationResult
|
|
41
41
|
import com.stripe.android.crypto.onramp.model.OnrampCreateCryptoPaymentTokenResult
|
|
42
|
+
import com.stripe.android.crypto.onramp.model.OnrampGetWalletOwnershipChallengeResult
|
|
42
43
|
import com.stripe.android.crypto.onramp.model.OnrampUserAttestationResult
|
|
43
44
|
import com.stripe.android.crypto.onramp.model.OnrampHasLinkAccountResult
|
|
44
45
|
import com.stripe.android.crypto.onramp.model.OnrampLogOutResult
|
|
@@ -46,6 +47,7 @@ import com.stripe.android.crypto.onramp.model.OnrampRegisterLinkUserResult
|
|
|
46
47
|
import com.stripe.android.crypto.onramp.model.OnrampRegisterWalletAddressResult
|
|
47
48
|
import com.stripe.android.crypto.onramp.model.OnrampRetrieveMissingIdentifiersResult
|
|
48
49
|
import com.stripe.android.crypto.onramp.model.OnrampSubmitIdentifiersResult
|
|
50
|
+
import com.stripe.android.crypto.onramp.model.OnrampSubmitWalletOwnershipSignatureResult
|
|
49
51
|
import com.stripe.android.crypto.onramp.model.OnrampTokenAuthenticationResult
|
|
50
52
|
import com.stripe.android.crypto.onramp.model.OnrampUpdatePhoneNumberResult
|
|
51
53
|
import com.stripe.android.crypto.onramp.model.OnrampVerifyIdentityResult
|
|
@@ -297,6 +299,66 @@ class OnrampSdkModule(
|
|
|
297
299
|
}
|
|
298
300
|
}
|
|
299
301
|
|
|
302
|
+
@ReactMethod
|
|
303
|
+
override fun getWalletOwnershipChallenge(
|
|
304
|
+
walletAddress: String,
|
|
305
|
+
network: String,
|
|
306
|
+
promise: Promise,
|
|
307
|
+
) {
|
|
308
|
+
val coordinator =
|
|
309
|
+
onrampCoordinator ?: run {
|
|
310
|
+
promise.resolve(createOnrampNotConfiguredError())
|
|
311
|
+
return
|
|
312
|
+
}
|
|
313
|
+
CoroutineScope(Dispatchers.IO).launch {
|
|
314
|
+
val cryptoNetwork = enumValues<CryptoNetwork>().firstOrNull { it.value == network }
|
|
315
|
+
if (cryptoNetwork == null) {
|
|
316
|
+
promise.resolve(createError(ErrorType.Unknown.toString(), "Invalid network: $network"))
|
|
317
|
+
return@launch
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
when (val result = coordinator.getWalletOwnershipChallenge(walletAddress, cryptoNetwork)) {
|
|
321
|
+
is OnrampGetWalletOwnershipChallengeResult.Completed -> {
|
|
322
|
+
promise.resolve(
|
|
323
|
+
WritableNativeMap().apply {
|
|
324
|
+
putMap("challenge", mapFromWalletOwnershipChallenge(result.challenge))
|
|
325
|
+
},
|
|
326
|
+
)
|
|
327
|
+
}
|
|
328
|
+
is OnrampGetWalletOwnershipChallengeResult.Failed -> {
|
|
329
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
@ReactMethod
|
|
336
|
+
override fun submitWalletOwnershipSignature(
|
|
337
|
+
challengeId: String,
|
|
338
|
+
signature: String,
|
|
339
|
+
promise: Promise,
|
|
340
|
+
) {
|
|
341
|
+
val coordinator =
|
|
342
|
+
onrampCoordinator ?: run {
|
|
343
|
+
promise.resolve(createOnrampNotConfiguredError())
|
|
344
|
+
return
|
|
345
|
+
}
|
|
346
|
+
CoroutineScope(Dispatchers.IO).launch {
|
|
347
|
+
when (val result = coordinator.submitWalletOwnershipSignature(challengeId, signature)) {
|
|
348
|
+
is OnrampSubmitWalletOwnershipSignatureResult.Completed -> {
|
|
349
|
+
promise.resolve(
|
|
350
|
+
WritableNativeMap().apply {
|
|
351
|
+
putMap("consumerWallet", mapFromCryptoConsumerWallet(result.consumerWallet))
|
|
352
|
+
},
|
|
353
|
+
)
|
|
354
|
+
}
|
|
355
|
+
is OnrampSubmitWalletOwnershipSignatureResult.Failed -> {
|
|
356
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
300
362
|
@ReactMethod
|
|
301
363
|
override fun attachKycInfo(
|
|
302
364
|
kycInfo: ReadableMap,
|
|
@@ -17,9 +17,9 @@ import org.robolectric.RobolectricTestRunner
|
|
|
17
17
|
@RunWith(RobolectricTestRunner::class)
|
|
18
18
|
class OnrampErrorsTest {
|
|
19
19
|
@Test
|
|
20
|
-
fun
|
|
20
|
+
fun createOnrampFailedError_withAppAttestationException_preservesApiFields() {
|
|
21
21
|
val error =
|
|
22
|
-
|
|
22
|
+
createApiOnrampException(
|
|
23
23
|
className = "com.stripe.android.crypto.onramp.exception.AppAttestationException",
|
|
24
24
|
reason = "android_package_name_mismatch",
|
|
25
25
|
operation = "configure",
|
|
@@ -67,9 +67,9 @@ class OnrampErrorsTest {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
@Test
|
|
70
|
-
fun
|
|
70
|
+
fun createOnrampFailedError_withUncategorizedApiError_preservesApiFields() {
|
|
71
71
|
val error =
|
|
72
|
-
|
|
72
|
+
createApiOnrampException(
|
|
73
73
|
className = "com.stripe.android.crypto.onramp.exception.UncategorizedException",
|
|
74
74
|
reason = "consumer_session_expired",
|
|
75
75
|
operation = "authorize",
|
|
@@ -93,11 +93,50 @@ class OnrampErrorsTest {
|
|
|
93
93
|
assertEquals("authentication_error", details.getString("type"))
|
|
94
94
|
assertEquals("Session expired. Please sign in again.", details.getString("message"))
|
|
95
95
|
assertEquals("Session expired. Please sign in again.", details.getString("userMessage"))
|
|
96
|
+
assertEquals("consumer_session_expired", details.getString("reason"))
|
|
96
97
|
assertEquals("req_auth", details.getString("requestId"))
|
|
97
98
|
assertTrue(details.getString("developerMessage")!!.contains("Code: consumer_session_expired"))
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
@Test
|
|
102
|
+
fun createOnrampFailedError_withAppAttestationUnavailableException_preservesSdkErrorFields() {
|
|
103
|
+
val underlyingError = IllegalStateException("Native Link is not available")
|
|
104
|
+
val error =
|
|
105
|
+
createAppAttestationUnavailableException(
|
|
106
|
+
underlyingError = underlyingError,
|
|
107
|
+
operation = "configure",
|
|
108
|
+
appPackageName = "com.example.app",
|
|
109
|
+
mode = "test",
|
|
110
|
+
sdkVersions =
|
|
111
|
+
listOf(
|
|
112
|
+
SDKVersion(name = "stripe-android", version = "23.10.0"),
|
|
113
|
+
SDKVersion(name = "stripe-react-native", version = "0.67.0"),
|
|
114
|
+
),
|
|
115
|
+
userMessage = "This app couldn't be verified. Contact the app developer for help.",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
val details = createOnrampFailedError(error).getMap("error")
|
|
119
|
+
|
|
120
|
+
assertNotNull(details)
|
|
121
|
+
assertEquals("Failed", details!!.getString("code"))
|
|
122
|
+
assertEquals("AppAttestationUnavailableError", details.getString("onrampErrorType"))
|
|
123
|
+
assertEquals(
|
|
124
|
+
"This app couldn't be verified. Contact the app developer for help.",
|
|
125
|
+
details.getString("message"),
|
|
126
|
+
)
|
|
127
|
+
assertEquals(
|
|
128
|
+
"This app couldn't be verified. Contact the app developer for help.",
|
|
129
|
+
details.getString("localizedMessage"),
|
|
130
|
+
)
|
|
131
|
+
assertEquals(
|
|
132
|
+
"This app couldn't be verified. Contact the app developer for help.",
|
|
133
|
+
details.getString("userMessage"),
|
|
134
|
+
)
|
|
135
|
+
assertEquals("app_attestation_unavailable", details.getString("stripeErrorCode"))
|
|
136
|
+
assertTrue(details.getString("developerMessage")!!.contains("operation: configure"))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private fun createApiOnrampException(
|
|
101
140
|
className: String,
|
|
102
141
|
reason: String,
|
|
103
142
|
operation: String,
|
|
@@ -120,7 +159,7 @@ class OnrampErrorsTest {
|
|
|
120
159
|
docUrl = docUrl,
|
|
121
160
|
)
|
|
122
161
|
val cause = APIException(stripeError = stripeError, requestId = requestId)
|
|
123
|
-
val
|
|
162
|
+
val apiErrorContext =
|
|
124
163
|
APIErrorContext(
|
|
125
164
|
reason = reason,
|
|
126
165
|
apiErrorCode = apiErrorCode,
|
|
@@ -130,41 +169,79 @@ class OnrampErrorsTest {
|
|
|
130
169
|
docUrl = docUrl,
|
|
131
170
|
underlyingError = cause,
|
|
132
171
|
)
|
|
133
|
-
val diagnosticContextClass =
|
|
134
|
-
Class.forName("com.stripe.android.crypto.onramp.exception.DiagnosticContext")
|
|
135
172
|
val diagnosticContext =
|
|
136
|
-
|
|
137
|
-
.getDeclaredConstructor(
|
|
138
|
-
List::class.java,
|
|
139
|
-
String::class.java,
|
|
140
|
-
String::class.java,
|
|
141
|
-
String::class.java,
|
|
142
|
-
).apply {
|
|
143
|
-
isAccessible = true
|
|
144
|
-
}.newInstance(
|
|
145
|
-
sdkVersions,
|
|
146
|
-
operation,
|
|
147
|
-
appPackageName,
|
|
148
|
-
mode,
|
|
149
|
-
)
|
|
173
|
+
createDiagnosticContext(sdkVersions, operation, appPackageName, mode)
|
|
150
174
|
|
|
151
|
-
// The exception classes in the `com.stripe.android.crypto.onramp.exception` package
|
|
152
|
-
// don't have public constructors, so we use reflection to create instances for testing.
|
|
153
175
|
val constructor =
|
|
154
176
|
Class
|
|
155
177
|
.forName(className)
|
|
156
178
|
.getDeclaredConstructor(
|
|
157
179
|
APIErrorContext::class.java,
|
|
158
|
-
|
|
180
|
+
diagnosticContext.javaClass,
|
|
159
181
|
String::class.java,
|
|
160
182
|
).apply {
|
|
161
183
|
isAccessible = true
|
|
162
184
|
}
|
|
163
185
|
|
|
164
186
|
return constructor.newInstance(
|
|
165
|
-
|
|
187
|
+
apiErrorContext,
|
|
166
188
|
diagnosticContext,
|
|
167
189
|
userMessage,
|
|
168
190
|
) as Exception
|
|
169
191
|
}
|
|
192
|
+
|
|
193
|
+
private fun createAppAttestationUnavailableException(
|
|
194
|
+
underlyingError: Throwable,
|
|
195
|
+
operation: String,
|
|
196
|
+
appPackageName: String,
|
|
197
|
+
mode: String,
|
|
198
|
+
sdkVersions: List<SDKVersion>,
|
|
199
|
+
userMessage: String,
|
|
200
|
+
): Exception {
|
|
201
|
+
val diagnosticContext =
|
|
202
|
+
createDiagnosticContext(sdkVersions, operation, appPackageName, mode)
|
|
203
|
+
val exceptionClass =
|
|
204
|
+
Class.forName(
|
|
205
|
+
"com.stripe.android.crypto.onramp.exception.AppAttestationUnavailableException",
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
val constructor =
|
|
209
|
+
exceptionClass
|
|
210
|
+
.getDeclaredConstructor(
|
|
211
|
+
Throwable::class.java,
|
|
212
|
+
diagnosticContext.javaClass,
|
|
213
|
+
String::class.java,
|
|
214
|
+
)
|
|
215
|
+
.apply {
|
|
216
|
+
isAccessible = true
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return constructor.newInstance(
|
|
220
|
+
underlyingError,
|
|
221
|
+
diagnosticContext,
|
|
222
|
+
userMessage,
|
|
223
|
+
) as Exception
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private fun createDiagnosticContext(
|
|
227
|
+
sdkVersions: List<SDKVersion>,
|
|
228
|
+
operation: String,
|
|
229
|
+
appPackageName: String,
|
|
230
|
+
mode: String,
|
|
231
|
+
): Any {
|
|
232
|
+
val diagnosticContextClass =
|
|
233
|
+
Class.forName("com.stripe.android.crypto.onramp.exception.DiagnosticContext")
|
|
234
|
+
val constructor =
|
|
235
|
+
diagnosticContextClass
|
|
236
|
+
.getDeclaredConstructor(
|
|
237
|
+
List::class.java,
|
|
238
|
+
String::class.java,
|
|
239
|
+
String::class.java,
|
|
240
|
+
String::class.java,
|
|
241
|
+
).apply {
|
|
242
|
+
isAccessible = true
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return constructor.newInstance(sdkVersions, operation, appPackageName, mode)
|
|
246
|
+
}
|
|
170
247
|
}
|
|
@@ -8,7 +8,9 @@ import com.reactnativestripesdk.ComplianceIdentifierFieldException
|
|
|
8
8
|
import com.reactnativestripesdk.InvalidIdentifiersArrayException
|
|
9
9
|
import com.reactnativestripesdk.mapAppearance
|
|
10
10
|
import com.reactnativestripesdk.mapConfig
|
|
11
|
+
import com.reactnativestripesdk.mapFromCryptoConsumerWallet
|
|
11
12
|
import com.reactnativestripesdk.mapFromKycInfo
|
|
13
|
+
import com.reactnativestripesdk.mapFromWalletOwnershipChallenge
|
|
12
14
|
import com.reactnativestripesdk.mapGooglePayConfig
|
|
13
15
|
import com.reactnativestripesdk.mapPaymentDetailsType
|
|
14
16
|
import com.reactnativestripesdk.mapToComplianceIdentifiers
|
|
@@ -16,6 +18,7 @@ import com.reactnativestripesdk.utils.readableArrayOf
|
|
|
16
18
|
import com.reactnativestripesdk.utils.readableMapOf
|
|
17
19
|
import com.stripe.android.core.model.CountryCode
|
|
18
20
|
import com.stripe.android.crypto.onramp.ExperimentalCryptoOnramp
|
|
21
|
+
import com.stripe.android.crypto.onramp.model.CryptoNetwork
|
|
19
22
|
import com.stripe.android.crypto.onramp.model.KycInfo
|
|
20
23
|
import com.stripe.android.crypto.onramp.model.PaymentMethodDisplayData
|
|
21
24
|
import com.stripe.android.googlepaylauncher.GooglePayEnvironment
|
|
@@ -593,6 +596,40 @@ class OnrampMappersTest {
|
|
|
593
596
|
assertFalse(address.hasKey("state"))
|
|
594
597
|
}
|
|
595
598
|
|
|
599
|
+
@Test
|
|
600
|
+
fun mapFromWalletOwnershipChallenge_MapsAllFields() {
|
|
601
|
+
val result =
|
|
602
|
+
mapFromWalletOwnershipChallenge(
|
|
603
|
+
challengeId = "cwoc_123",
|
|
604
|
+
walletAddress = "0x1234",
|
|
605
|
+
network = CryptoNetwork.Solana,
|
|
606
|
+
message = "Sign this exact message",
|
|
607
|
+
expiresAt = "2026-07-15T16:00:00Z",
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
assertEquals("cwoc_123", result.getString("challengeId"))
|
|
611
|
+
assertEquals("0x1234", result.getString("walletAddress"))
|
|
612
|
+
assertEquals("solana", result.getString("network"))
|
|
613
|
+
assertEquals("Sign this exact message", result.getString("message"))
|
|
614
|
+
assertEquals("2026-07-15T16:00:00Z", result.getString("expiresAt"))
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
@Test
|
|
618
|
+
fun mapFromCryptoConsumerWallet_MapsAllFields() {
|
|
619
|
+
val result =
|
|
620
|
+
mapFromCryptoConsumerWallet(
|
|
621
|
+
id = "ccw_123",
|
|
622
|
+
network = CryptoNetwork.Ethereum,
|
|
623
|
+
walletAddress = "0xabcd",
|
|
624
|
+
verifiedOwnership = true,
|
|
625
|
+
)
|
|
626
|
+
|
|
627
|
+
assertEquals("ccw_123", result.getString("id"))
|
|
628
|
+
assertEquals("0xabcd", result.getString("walletAddress"))
|
|
629
|
+
assertEquals("ethereum", result.getString("network"))
|
|
630
|
+
assertTrue(result.getBoolean("verifiedOwnership"))
|
|
631
|
+
}
|
|
632
|
+
|
|
596
633
|
@Test
|
|
597
634
|
fun mapToComplianceIdentifiers_ValidIdentifiers_ReturnsIdentifiers() {
|
|
598
635
|
val identifiers =
|