From 136fe179f20e126ac688a962e0b7f79a13ce8909 Mon Sep 17 00:00:00 2001 From: Carlos Munoz Date: Thu, 4 Sep 2025 13:18:00 -0700 Subject: [PATCH 1/5] Fix wallet address network mismatch issue - Add network-specific default wallet addresses for all supported crypto networks - Auto-update wallet address when network selection changes - Prevent Ethereum addresses being used for Solana/Bitcoin/other networks - Add visual feedback showing current network format - Fix address format validation errors when switching networks Fixes: - Ethereum: 0x742d35... (EVM networks) - Solana: 9WzDXwBbmkg8... (base58) - Bitcoin: 1A1zP1eP... (base58 + version) - Stellar: GDQP2KPQGKI... (base32) - And more network-specific formats This resolves the reported issue where users selecting Solana network but using an Ethereum address format were getting validation errors. Committed-By-Agent: cursor --- example/src/screens/CryptoOnrampScreen.tsx | 51 +++++++++++++++++++--- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/example/src/screens/CryptoOnrampScreen.tsx b/example/src/screens/CryptoOnrampScreen.tsx index 92385d3b0e..fb566a3a55 100644 --- a/example/src/screens/CryptoOnrampScreen.tsx +++ b/example/src/screens/CryptoOnrampScreen.tsx @@ -649,14 +649,52 @@ export function RegisterWalletAddressScreen({ onWalletRegistered?: (address: string) => void; }) { const { registerWalletAddress } = useOnramp(); - const [walletAddress, setWalletAddress] = useState( - '0x742d35Cc6634C0532925a3b844Bc454e4438f44e' - ); const [network, setNetwork] = useState( Onramp.CryptoNetwork.ethereum ); + + // Sample addresses for different networks + const getDefaultAddressForNetwork = useCallback( + (cryptoNetwork: Onramp.CryptoNetwork): string => { + switch (cryptoNetwork) { + case Onramp.CryptoNetwork.ethereum: + case Onramp.CryptoNetwork.polygon: + case Onramp.CryptoNetwork.avalanche: + case Onramp.CryptoNetwork.base: + case Onramp.CryptoNetwork.optimism: + case Onramp.CryptoNetwork.worldchain: + return '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'; + case Onramp.CryptoNetwork.solana: + return '9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM'; + case Onramp.CryptoNetwork.bitcoin: + return '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'; + case Onramp.CryptoNetwork.stellar: + return 'GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37'; + case Onramp.CryptoNetwork.aptos: + return '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b'; + case Onramp.CryptoNetwork.xrpl: + return 'rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH'; + default: + return '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'; + } + }, + [] + ); + + const [walletAddress, setWalletAddress] = useState( + getDefaultAddressForNetwork(Onramp.CryptoNetwork.ethereum) + ); const [response, setResponse] = useState(null); + // Update wallet address when network changes + const handleNetworkChange = useCallback( + (newNetwork: Onramp.CryptoNetwork) => { + setNetwork(newNetwork); + setWalletAddress(getDefaultAddressForNetwork(newNetwork)); + }, + [getDefaultAddressForNetwork] + ); + const handleRegisterWallet = useCallback(async () => { setResponse(null); const result = await registerWalletAddress(walletAddress, network); @@ -681,14 +719,17 @@ export function RegisterWalletAddressScreen({ + + Current format: {network} address (auto-updated when network changes) + Network: - setNetwork(itemValue as Onramp.CryptoNetwork) + handleNetworkChange(itemValue as Onramp.CryptoNetwork) } style={styles.textInput} > From 5250178760aae04d181949e50e449c989f037175 Mon Sep 17 00:00:00 2001 From: Carlos Munoz Date: Thu, 4 Sep 2025 13:29:43 -0700 Subject: [PATCH 2/5] Fix onramp session destination network mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Track wallet network selection (Solana, Ethereum, etc.) during registration - Map crypto networks to appropriate destination currencies (SOL, ETH, BTC, etc.) - Pass correct destinationNetwork and destinationCurrency to createOnrampSession - Add network-specific currency mapping for all supported networks - Display selected network in wallet status section Fixes the core issue where: - User registers Solana wallet address - But createOnrampSession used hardcoded 'ethereum' network + 'eth' currency - Causing validation/processing errors on the backend Now correctly maps: - Solana → sol currency, solana network - Bitcoin → btc currency, bitcoin network - Ethereum/EVM → eth currency, respective network - And all other supported networks This resolves the reported Solana/Ethereum destination mismatch error. Committed-By-Agent: cursor --- example/src/screens/CryptoOnrampScreen.tsx | 106 +++++++++++++++++++-- 1 file changed, 100 insertions(+), 6 deletions(-) diff --git a/example/src/screens/CryptoOnrampScreen.tsx b/example/src/screens/CryptoOnrampScreen.tsx index fb566a3a55..d65dfddad9 100644 --- a/example/src/screens/CryptoOnrampScreen.tsx +++ b/example/src/screens/CryptoOnrampScreen.tsx @@ -66,6 +66,8 @@ export default function CryptoOnrampScreen() { // Wallet address from registration const [walletAddress, setWalletAddress] = useState(null); + const [walletNetwork, setWalletNetwork] = + useState(null); // Onramp session data const [onrampSessionId, setOnrampSessionId] = useState(null); @@ -292,6 +294,81 @@ export default function CryptoOnrampScreen() { } }, [createCryptoPaymentToken]); + // Map crypto networks to destination currencies and networks for onramp session + const getDestinationParamsForNetwork = useCallback( + ( + network: Onramp.CryptoNetwork + ): { + destinationNetwork: string; + destinationCurrency: string; + } => { + switch (network) { + case Onramp.CryptoNetwork.ethereum: + return { + destinationNetwork: 'ethereum', + destinationCurrency: 'eth', + }; + case Onramp.CryptoNetwork.polygon: + return { + destinationNetwork: 'polygon', + destinationCurrency: 'eth', + }; + case Onramp.CryptoNetwork.avalanche: + return { + destinationNetwork: 'avalanche', + destinationCurrency: 'avax', + }; + case Onramp.CryptoNetwork.base: + return { + destinationNetwork: 'base', + destinationCurrency: 'eth', + }; + case Onramp.CryptoNetwork.optimism: + return { + destinationNetwork: 'optimism', + destinationCurrency: 'eth', + }; + case Onramp.CryptoNetwork.worldchain: + return { + destinationNetwork: 'worldchain', + destinationCurrency: 'eth', + }; + case Onramp.CryptoNetwork.solana: + return { + destinationNetwork: 'solana', + destinationCurrency: 'sol', + }; + case Onramp.CryptoNetwork.bitcoin: + return { + destinationNetwork: 'bitcoin', + destinationCurrency: 'btc', + }; + case Onramp.CryptoNetwork.stellar: + return { + destinationNetwork: 'stellar', + destinationCurrency: 'xlm', + }; + case Onramp.CryptoNetwork.aptos: + return { + destinationNetwork: 'aptos', + destinationCurrency: 'apt', + }; + case Onramp.CryptoNetwork.xrpl: + return { + destinationNetwork: 'xrpl', + destinationCurrency: 'xrp', + }; + default: + // Default to Ethereum for unknown networks + return { + destinationNetwork: 'ethereum', + destinationCurrency: 'eth', + }; + } + }, + [] + ); + const validateOnrampSessionParams = useCallback((): { isValid: boolean; message?: string; @@ -299,7 +376,8 @@ export default function CryptoOnrampScreen() { const missingItems: string[] = []; if (!customerId) missingItems.push('customer authentication'); - if (!walletAddress) missingItems.push('wallet address registration'); + if (!walletAddress || !walletNetwork) + missingItems.push('wallet address registration'); if (!paymentDisplayData) missingItems.push('payment method selection'); if (!cryptoPaymentToken) missingItems.push('crypto payment token creation'); if (!authToken) missingItems.push('authentication token'); @@ -313,6 +391,7 @@ export default function CryptoOnrampScreen() { }, [ customerId, walletAddress, + walletNetwork, paymentDisplayData, cryptoPaymentToken, authToken, @@ -328,11 +407,18 @@ export default function CryptoOnrampScreen() { setIsCreatingSession(true); try { + // Get the correct destination network and currency based on wallet network + const destinationParams = getDestinationParamsForNetwork(walletNetwork!); + const result = await createOnrampSession( cryptoPaymentToken!, walletAddress!, customerId!, - authToken! + authToken!, + destinationParams.destinationNetwork, + 10.0, // sourceAmount + 'usd', // sourceCurrency + destinationParams.destinationCurrency ); if (result.success) { @@ -357,8 +443,10 @@ export default function CryptoOnrampScreen() { } }, [ validateOnrampSessionParams, + getDestinationParamsForNetwork, cryptoPaymentToken, walletAddress, + walletNetwork, customerId, authToken, ]); @@ -490,11 +578,12 @@ export default function CryptoOnrampScreen() { )} - {walletAddress && ( + {walletAddress && walletNetwork && ( {'Wallet Address: ' + walletAddress} + {'Network: ' + walletNetwork} )} @@ -597,7 +686,12 @@ export default function CryptoOnrampScreen() { {isLinkUser === true && customerId != null && ( - + { + setWalletAddress(address); + setWalletNetwork(network); + }} + /> )} @@ -646,7 +740,7 @@ export default function CryptoOnrampScreen() { export function RegisterWalletAddressScreen({ onWalletRegistered, }: { - onWalletRegistered?: (address: string) => void; + onWalletRegistered?: (address: string, network: Onramp.CryptoNetwork) => void; }) { const { registerWalletAddress } = useOnramp(); const [network, setNetwork] = useState( @@ -709,7 +803,7 @@ export function RegisterWalletAddressScreen({ ); } else { setResponse(`Wallet registered`); - onWalletRegistered?.(walletAddress); + onWalletRegistered?.(walletAddress, network); } }, [walletAddress, network, registerWalletAddress, onWalletRegistered]); From 3638ee73c5f0d50268a6b6b0103644ccd97a3f61 Mon Sep 17 00:00:00 2001 From: Carlos Munoz Date: Thu, 4 Sep 2025 13:53:49 -0700 Subject: [PATCH 3/5] Remove dangerous default values from createOnrampSession API - Remove default destinationNetwork, destinationCurrency, etc. from createOnrampSession - Make all parameters required to prevent accidental network/currency mismatches - Update convenience function to require all parameters explicitly - Add missing customerIpAddress parameter to CryptoOnrampScreen call - Update JSDoc to show examples instead of defaults This prevents future issues where: - Someone calls createOnrampSession without destinationCurrency - It defaults to 'eth' even for Solana/Bitcoin wallets - Causing the same network mismatch errors we just fixed Now callers MUST explicitly provide all values, making the API safer. Committed-By-Agent: cursor --- example/server/onrampBackend.ts | 30 +++++++++++----------- example/src/screens/CryptoOnrampScreen.tsx | 3 ++- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/example/server/onrampBackend.ts b/example/server/onrampBackend.ts index 0505f4c8ae..073f8c6280 100644 --- a/example/server/onrampBackend.ts +++ b/example/server/onrampBackend.ts @@ -166,22 +166,22 @@ export class OnrampBackend { * @param walletAddress Destination wallet address * @param cryptoCustomerId Customer ID from authentication * @param authToken Authorization token - * @param destinationNetwork Destination network (default: "ethereum") - * @param sourceAmount Source amount (default: 10.0) - * @param sourceCurrency Source currency (default: "usd") - * @param destinationCurrency Destination currency (default: "eth") - * @param customerIpAddress Customer IP address (default: "127.0.0.1") + * @param destinationNetwork Destination network (e.g., "ethereum", "solana", "bitcoin") + * @param sourceAmount Source amount in USD + * @param sourceCurrency Source currency (e.g., "usd") + * @param destinationCurrency Destination currency (e.g., "eth", "sol", "btc") + * @param customerIpAddress Customer IP address */ async createOnrampSession( paymentToken: string, walletAddress: string, cryptoCustomerId: string, authToken: string, - destinationNetwork: string = 'ethereum', - sourceAmount: number = 10.0, - sourceCurrency: string = 'usd', - destinationCurrency: string = 'eth', - customerIpAddress: string = '127.0.0.1' + destinationNetwork: string, + sourceAmount: number, + sourceCurrency: string, + destinationCurrency: string, + customerIpAddress: string ): Promise> { const requestBody: CreateOnrampSessionRequest = { ui_mode: 'headless', @@ -247,11 +247,11 @@ export const createOnrampSession = async ( walletAddress: string, cryptoCustomerId: string, authToken: string, - destinationNetwork?: string, - sourceAmount?: number, - sourceCurrency?: string, - destinationCurrency?: string, - customerIpAddress?: string + destinationNetwork: string, + sourceAmount: number, + sourceCurrency: string, + destinationCurrency: string, + customerIpAddress: string ): Promise> => { return defaultClient.createOnrampSession( paymentToken, diff --git a/example/src/screens/CryptoOnrampScreen.tsx b/example/src/screens/CryptoOnrampScreen.tsx index d65dfddad9..fdcc9d6b0a 100644 --- a/example/src/screens/CryptoOnrampScreen.tsx +++ b/example/src/screens/CryptoOnrampScreen.tsx @@ -418,7 +418,8 @@ export default function CryptoOnrampScreen() { destinationParams.destinationNetwork, 10.0, // sourceAmount 'usd', // sourceCurrency - destinationParams.destinationCurrency + destinationParams.destinationCurrency, + '127.0.0.1' // customerIpAddress ); if (result.success) { From 6c63dd2006c9266b8ba914a7920932e7b2938bf4 Mon Sep 17 00:00:00 2001 From: Carlos Munoz Date: Thu, 4 Sep 2025 14:37:54 -0700 Subject: [PATCH 4/5] Spotless --- .../FakeOnrampSdkModule.kt | 29 +- .../reactnativestripesdk/StripeSdkModule.kt | 5 +- .../reactnativestripesdk/StripeSdkPackage.kt | 9 +- .../com/reactnativestripesdk/utils/Errors.kt | 8 +- .../com/reactnativestripesdk/utils/Mappers.kt | 9 +- .../reactnativestripesdk/OnrampSdkModule.kt | 312 ++++++++++-------- 6 files changed, 206 insertions(+), 166 deletions(-) diff --git a/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt b/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt index eeacc52951..82c9d3e76d 100644 --- a/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt +++ b/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt @@ -12,32 +12,35 @@ class FakeOnrampSdkModule( ) : NativeOnrampSdkModuleSpec(reactContext) { override fun initialise( params: ReadableMap?, - promise: Promise? + promise: Promise?, ) { promise?.resolve(null) } override fun configureOnramp( config: ReadableMap?, - promise: Promise? + promise: Promise?, ) { promise?.resolve( createFailedError( NotImplementedError( "StripeCryptoOnramp is not available. " + - "To enable, add the 'ext { includeOnramp = true }' to your app's build.gradle." - ) - ) + "To enable, add the 'ext { includeOnramp = true }' to your app's build.gradle.", + ), + ), ) } - override fun hasLinkAccount(email: String?, promise: Promise?) { + override fun hasLinkAccount( + email: String?, + promise: Promise?, + ) { promise?.resolve(createFailedError(NotImplementedError())) } override fun registerLinkUser( info: ReadableMap?, - promise: Promise? + promise: Promise?, ) { promise?.resolve(createFailedError(NotImplementedError())) } @@ -45,21 +48,21 @@ class FakeOnrampSdkModule( override fun registerWalletAddress( walletAddress: String?, network: String?, - promise: Promise? + promise: Promise?, ) { promise?.resolve(createFailedError(NotImplementedError())) } override fun attachKycInfo( kycInfo: ReadableMap?, - promise: Promise? + promise: Promise?, ) { promise?.resolve(createFailedError(NotImplementedError())) } override fun updatePhoneNumber( phone: String?, - promise: Promise? + promise: Promise?, ) { promise?.resolve(createFailedError(NotImplementedError())) } @@ -75,7 +78,7 @@ class FakeOnrampSdkModule( override fun collectPaymentMethod( paymentMethod: String?, platformPayParams: ReadableMap?, - promise: Promise? + promise: Promise?, ) { promise?.resolve(createFailedError(NotImplementedError())) } @@ -90,14 +93,14 @@ class FakeOnrampSdkModule( override fun performCheckout( onrampSessionId: String?, - promise: Promise? + promise: Promise?, ) { promise?.resolve(createFailedError(NotImplementedError())) } override fun onrampAuthorize( linkAuthIntentId: String?, - promise: Promise? + promise: Promise?, ) { promise?.resolve(createFailedError(NotImplementedError())) } diff --git a/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt b/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt index 520d8b0c0d..bdd4cbd416 100644 --- a/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +++ b/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt @@ -243,7 +243,7 @@ class StripeSdkModule( // Store the original ReadableMap for custom payment methods bundle.putSerializable( "customPaymentMethodConfigurationReadableMap", - customPaymentMethodConfig.toHashMap() + customPaymentMethodConfig.toHashMap(), ) } @@ -1400,7 +1400,8 @@ class StripeSdkModule( private fun setupComposeCompatView() { UiThreadUtil.runOnUiThread { composeCompatView = - composeCompatView ?: StripeAbstractComposeView.CompatView(context = reactApplicationContext) + composeCompatView ?: StripeAbstractComposeView + .CompatView(context = reactApplicationContext) .also { currentActivity?.findViewById(android.R.id.content)?.addView( it, diff --git a/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt b/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt index 621844ee5c..fe9541664a 100644 --- a/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +++ b/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt @@ -28,10 +28,11 @@ class StripeSdkPackage : BaseReactPackage() { } override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { - val moduleList: Array> = arrayOf( - StripeSdkModule::class.java, - getOnrampModuleClass(), - ) + val moduleList: Array> = + arrayOf( + StripeSdkModule::class.java, + getOnrampModuleClass(), + ) val reactModuleInfoMap: MutableMap = HashMap() for (moduleClass in moduleList) { val reactModule = moduleClass.getAnnotation(ReactModule::class.java) ?: continue diff --git a/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt b/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt index cf99f645f0..4de126973a 100644 --- a/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +++ b/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt @@ -178,13 +178,9 @@ internal fun createError( return mapError(code, error.message, error.localizedMessage, null, null, null) } -internal fun createCanceledError(message: String? = null): WritableMap { - return createError(ErrorType.Canceled.toString(), message) -} +internal fun createCanceledError(message: String? = null): WritableMap = createError(ErrorType.Canceled.toString(), message) -internal fun createFailedError(error: Throwable): WritableMap { - return createError(ErrorType.Failed.toString(), error) -} +internal fun createFailedError(error: Throwable): WritableMap = createError(ErrorType.Failed.toString(), error) internal fun createMissingInitError(): WritableMap = createError( diff --git a/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt b/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt index 3fc40c14c0..be5610e26a 100644 --- a/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +++ b/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt @@ -30,9 +30,7 @@ import com.stripe.android.model.Token import com.stripe.android.paymentelement.ExperimentalCustomPaymentMethodsApi import com.stripe.android.paymentsheet.PaymentSheet -internal fun createEmptyResult(): WritableMap { - return WritableNativeMap() -} +internal fun createEmptyResult(): WritableMap = WritableNativeMap() internal fun createResult( key: String, @@ -561,7 +559,7 @@ internal fun mapNextAction( NextActionType.UseStripeSdk, NextActionType.UpiAwaitNotification, null, - -> { + -> { return null } NextActionType.DisplayBoletoDetails -> { @@ -680,8 +678,7 @@ internal fun mapToBillingDetails( return paymentMethodBillingDetailsBuilder.build() } -internal fun mapToMetadata(metadata: ReadableMap?): Map? = - metadata?.toHashMap()?.mapValues { it.value.toString() } +internal fun mapToMetadata(metadata: ReadableMap?): Map? = metadata?.toHashMap()?.mapValues { it.value.toString() } internal fun mapToShippingDetails(shippingDetails: ReadableMap?): ConfirmPaymentIntentParams.Shipping? { if (shippingDetails == null) { diff --git a/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt b/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt index 572765b165..f8afbd23a6 100644 --- a/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt +++ b/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt @@ -179,9 +179,11 @@ class OnrampSdkModule( return } - val coordinator = OnrampCoordinator.Builder() - .build(application, SavedStateHandle()) - .also { this.onrampCoordinator = it } + val coordinator = + OnrampCoordinator + .Builder() + .build(application, SavedStateHandle()) + .also { this.onrampCoordinator = it } CoroutineScope(Dispatchers.IO).launch { val appearanceMap = config.getMap("appearance") @@ -194,11 +196,12 @@ class OnrampSdkModule( val displayName = config.getString("merchantDisplayName") ?: "" - val configuration = OnrampConfiguration( - merchantDisplayName = displayName, - publishableKey = publishableKey, - appearance = appearance - ) + val configuration = + OnrampConfiguration( + merchantDisplayName = displayName, + publishableKey = publishableKey, + appearance = appearance, + ) val configureResult = coordinator.configure(configuration) @@ -231,23 +234,24 @@ class OnrampSdkModule( return } - val onrampCallbacks = OnrampCallbacks( - authenticateUserCallback = { result -> - handleOnrampAuthenticationResult(result, authenticateUserPromise!!) - }, - verifyIdentityCallback = { result -> - handleOnrampIdentityVerificationResult(result, identityVerificationPromise!!) - }, - collectPaymentCallback = { result -> - handleOnrampCollectPaymentResult(result, collectPaymentPromise!!) - }, - authorizeCallback = { result -> - handleOnrampAuthorizationResult(result, authorizePromise!!) - }, - checkoutCallback = { result -> - handleOnrampCheckoutResult(result, checkoutPromise!!) - } - ) + val onrampCallbacks = + OnrampCallbacks( + authenticateUserCallback = { result -> + handleOnrampAuthenticationResult(result, authenticateUserPromise!!) + }, + verifyIdentityCallback = { result -> + handleOnrampIdentityVerificationResult(result, identityVerificationPromise!!) + }, + collectPaymentCallback = { result -> + handleOnrampCollectPaymentResult(result, collectPaymentPromise!!) + }, + authorizeCallback = { result -> + handleOnrampAuthorizationResult(result, authorizePromise!!) + }, + checkoutCallback = { result -> + handleOnrampCheckoutResult(result, checkoutPromise!!) + }, + ) try { onrampPresenter = onrampCoordinator!!.createPresenter(activity, onrampCallbacks) @@ -262,10 +266,11 @@ class OnrampSdkModule( email: String, promise: Promise, ) { - val coordinator = onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = + onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { when (val result = coordinator.hasLinkAccount(email)) { is OnrampHasLinkAccountResult.Completed -> { @@ -283,17 +288,19 @@ class OnrampSdkModule( info: ReadableMap, promise: Promise, ) { - val coordinator = onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = + onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { - val linkUserInfo = LinkUserInfo( - email = info.getString("email") ?: "", - phone = info.getString("phone") ?: "", - country = info.getString("country") ?: "", - fullName = info.getString("fullName"), - ) + val linkUserInfo = + LinkUserInfo( + email = info.getString("email") ?: "", + phone = info.getString("phone") ?: "", + country = info.getString("country") ?: "", + fullName = info.getString("fullName"), + ) val result = coordinator.registerLinkUser(linkUserInfo) when (result) { @@ -311,12 +318,13 @@ class OnrampSdkModule( override fun registerWalletAddress( walletAddress: String, network: String, - promise: Promise + promise: Promise, ) { - val coordinator = onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = + onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { val cryptoNetwork = enumValues().firstOrNull { it.value == network } if (cryptoNetwork == null) { @@ -338,20 +346,21 @@ class OnrampSdkModule( @ReactMethod override fun attachKycInfo( kycInfo: ReadableMap, - promise: Promise + promise: Promise, ) { - val coordinator = onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = + onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { val firstName = kycInfo.getString("firstName") if (firstName.isNullOrEmpty()) { promise.resolve( createError( ErrorType.Unknown.toString(), - "Missing required field: firstName" - ) + "Missing required field: firstName", + ), ) return@launch } @@ -360,8 +369,8 @@ class OnrampSdkModule( promise.resolve( createError( ErrorType.Unknown.toString(), - "Missing required field: lastName" - ) + "Missing required field: lastName", + ), ) return@launch } @@ -370,8 +379,8 @@ class OnrampSdkModule( promise.resolve( createError( ErrorType.Unknown.toString(), - "Missing required field: idNumber" - ) + "Missing required field: idNumber", + ), ) return@launch } @@ -387,37 +396,39 @@ class OnrampSdkModule( DateOfBirth( day = dateOfBirthMap.getInt("day"), month = dateOfBirthMap.getInt("month"), - year = dateOfBirthMap.getInt("year") + year = dateOfBirthMap.getInt("year"), ) } else { promise.resolve( createError( ErrorType.Unknown.toString(), - "Missing required field: dateOfBirth" - ) + "Missing required field: dateOfBirth", + ), ) return@launch } val addressMap = kycInfo.getMap("address") - val addressObj = addressMap?.let { - PaymentSheet.Address( - city = it.getString("city"), - country = it.getString("country"), - line1 = it.getString("line1"), - line2 = it.getString("line2"), - postalCode = it.getString("postalCode"), - state = it.getString("state"), + val addressObj = + addressMap?.let { + PaymentSheet.Address( + city = it.getString("city"), + country = it.getString("country"), + line1 = it.getString("line1"), + line2 = it.getString("line2"), + postalCode = it.getString("postalCode"), + state = it.getString("state"), + ) + } ?: PaymentSheet.Address() + + val kycInfoObj = + KycInfo( + firstName = firstName, + lastName = lastName, + idNumber = idNumber, + dateOfBirth = dob, + address = addressObj, ) - } ?: PaymentSheet.Address() - - val kycInfoObj = KycInfo( - firstName = firstName, - lastName = lastName, - idNumber = idNumber, - dateOfBirth = dob, - address = addressObj, - ) when (val result = coordinator.attachKycInfo(kycInfoObj)) { is OnrampAttachKycInfoResult.Completed -> { @@ -431,11 +442,15 @@ class OnrampSdkModule( } @ReactMethod - override fun updatePhoneNumber(phone: String, promise: Promise) { - val coordinator = onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + override fun updatePhoneNumber( + phone: String, + promise: Promise, + ) { + val coordinator = + onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { when (val result = coordinator.updatePhoneNumber(phone)) { OnrampUpdatePhoneNumberResult.Completed -> { @@ -450,10 +465,11 @@ class OnrampSdkModule( @ReactMethod override fun authenticateUser(promise: Promise) { - val presenter = onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val presenter = + onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } authenticateUserPromise = promise @@ -462,10 +478,11 @@ class OnrampSdkModule( @ReactMethod override fun verifyIdentity(promise: Promise) { - val presenter = onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val presenter = + onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } identityVerificationPromise = promise @@ -476,25 +493,27 @@ class OnrampSdkModule( override fun collectPaymentMethod( paymentMethod: String, platformPayParams: ReadableMap, - promise: Promise + promise: Promise, ) { - val presenter = onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val presenter = + onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } - val method = when (paymentMethod) { - "Card" -> PaymentMethodType.Card - "BankAccount" -> PaymentMethodType.BankAccount - else -> { - promise.resolve( - createFailedError( - IllegalArgumentException("Unsupported payment method: $paymentMethod") + val method = + when (paymentMethod) { + "Card" -> PaymentMethodType.Card + "BankAccount" -> PaymentMethodType.BankAccount + else -> { + promise.resolve( + createFailedError( + IllegalArgumentException("Unsupported payment method: $paymentMethod"), + ), ) - ) - return + return + } } - } collectPaymentPromise = promise @@ -503,10 +522,11 @@ class OnrampSdkModule( @ReactMethod override fun createCryptoPaymentToken(promise: Promise) { - val coordinator = onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = + onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { val result = coordinator.createCryptoPaymentToken() @@ -519,12 +539,13 @@ class OnrampSdkModule( @ReactMethod override fun performCheckout( onrampSessionId: String, - promise: Promise + promise: Promise, ) { - val presenter = onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val presenter = + onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } val checkoutHandler: suspend () -> String = { checkoutClientSecretDeferred = CompletableDeferred() @@ -548,18 +569,22 @@ class OnrampSdkModule( checkoutClientSecretDeferred?.complete(clientSecret) } else { checkoutClientSecretDeferred?.completeExceptionally( - RuntimeException("Failed to provide checkout client secret") + RuntimeException("Failed to provide checkout client secret"), ) } checkoutClientSecretDeferred = null } @ReactMethod - override fun onrampAuthorize(linkAuthIntentId: String, promise: Promise) { - val presenter = onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + override fun onrampAuthorize( + linkAuthIntentId: String, + promise: Promise, + ) { + val presenter = + onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } authorizePromise = promise @@ -568,10 +593,11 @@ class OnrampSdkModule( @ReactMethod override fun logout(promise: Promise) { - val coordinator = onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = + onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } promise.resolve(createFailedError(NotImplementedError())) } @@ -647,7 +673,10 @@ class OnrampSdkModule( ) } - private fun handleOnrampAuthenticationResult(result: OnrampAuthenticateResult, promise: Promise) { + private fun handleOnrampAuthenticationResult( + result: OnrampAuthenticateResult, + promise: Promise, + ) { when (result) { is OnrampAuthenticateResult.Completed -> { promise.resolveString("customerId", result.customerId) @@ -663,7 +692,7 @@ class OnrampSdkModule( private fun handleOnrampIdentityVerificationResult( result: OnrampVerifyIdentityResult, - promise: Promise + promise: Promise, ) { when (result) { is OnrampVerifyIdentityResult.Completed -> { @@ -680,14 +709,15 @@ class OnrampSdkModule( private fun handleOnrampCollectPaymentResult( result: OnrampCollectPaymentMethodResult, - promise: Promise + promise: Promise, ) { when (result) { is OnrampCollectPaymentMethodResult.Completed -> { val displayData = Arguments.createMap() - val icon = currentActivity - ?.let { ContextCompat.getDrawable(it, result.displayData.iconRes) } - ?.let { "data:image/png;base64," + getBase64FromBitmap(getBitmapFromDrawable(it)) } + val icon = + currentActivity + ?.let { ContextCompat.getDrawable(it, result.displayData.iconRes) } + ?.let { "data:image/png;base64," + getBase64FromBitmap(getBitmapFromDrawable(it)) } displayData.putString("icon", icon) displayData.putString("label", result.displayData.label) result.displayData.sublabel?.let { displayData.putString("sublabel", it) } @@ -702,21 +732,24 @@ class OnrampSdkModule( } } - private fun handleOnrampAuthorizationResult(result: OnrampAuthorizeResult, promise: Promise) { + private fun handleOnrampAuthorizationResult( + result: OnrampAuthorizeResult, + promise: Promise, + ) { when (result) { is OnrampAuthorizeResult.Consented -> { promise.resolve( WritableNativeMap().apply { putString("status", "Consented") putString("customerId", result.customerId) - } + }, ) } is OnrampAuthorizeResult.Denied -> { promise.resolve( WritableNativeMap().apply { putString("status", "Denied") - } + }, ) } is OnrampAuthorizeResult.Canceled -> { @@ -728,7 +761,10 @@ class OnrampSdkModule( } } - private fun handleOnrampCheckoutResult(result: OnrampCheckoutResult, promise: Promise) { + private fun handleOnrampCheckoutResult( + result: OnrampCheckoutResult, + promise: Promise, + ) { when (result) { is OnrampCheckoutResult.Completed -> { promise.resolveVoid() @@ -744,7 +780,7 @@ class OnrampSdkModule( private fun handleOnrampCreateCryptoPaymentTokenResult( result: OnrampCreateCryptoPaymentTokenResult, - promise: Promise + promise: Promise, ) { when (result) { is OnrampCreateCryptoPaymentTokenResult.Completed -> { @@ -760,11 +796,17 @@ class OnrampSdkModule( resolve(createEmptyResult()) } - private fun Promise.resolveString(key: String, value: String) { + private fun Promise.resolveString( + key: String, + value: String, + ) { resolve(WritableNativeMap().apply { putString(key, value) }) } - private fun Promise.resolveBoolean(key: String, value: Boolean) { + private fun Promise.resolveBoolean( + key: String, + value: Boolean, + ) { resolve(WritableNativeMap().apply { putBoolean(key, value) }) } } From 7e1bfe1da9f1068f9b703cdd10fa96f3ad2dbb4c Mon Sep 17 00:00:00 2001 From: Carlos Munoz Date: Thu, 4 Sep 2025 14:45:17 -0700 Subject: [PATCH 5/5] Revert "Spotless" This reverts commit 6c63dd2006c9266b8ba914a7920932e7b2938bf4. --- .../FakeOnrampSdkModule.kt | 29 +- .../reactnativestripesdk/StripeSdkModule.kt | 5 +- .../reactnativestripesdk/StripeSdkPackage.kt | 9 +- .../com/reactnativestripesdk/utils/Errors.kt | 8 +- .../com/reactnativestripesdk/utils/Mappers.kt | 9 +- .../reactnativestripesdk/OnrampSdkModule.kt | 312 ++++++++---------- 6 files changed, 166 insertions(+), 206 deletions(-) diff --git a/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt b/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt index 82c9d3e76d..eeacc52951 100644 --- a/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt +++ b/android/src/main/java/com/reactnativestripesdk/FakeOnrampSdkModule.kt @@ -12,35 +12,32 @@ class FakeOnrampSdkModule( ) : NativeOnrampSdkModuleSpec(reactContext) { override fun initialise( params: ReadableMap?, - promise: Promise?, + promise: Promise? ) { promise?.resolve(null) } override fun configureOnramp( config: ReadableMap?, - promise: Promise?, + promise: Promise? ) { promise?.resolve( createFailedError( NotImplementedError( "StripeCryptoOnramp is not available. " + - "To enable, add the 'ext { includeOnramp = true }' to your app's build.gradle.", - ), - ), + "To enable, add the 'ext { includeOnramp = true }' to your app's build.gradle." + ) + ) ) } - override fun hasLinkAccount( - email: String?, - promise: Promise?, - ) { + override fun hasLinkAccount(email: String?, promise: Promise?) { promise?.resolve(createFailedError(NotImplementedError())) } override fun registerLinkUser( info: ReadableMap?, - promise: Promise?, + promise: Promise? ) { promise?.resolve(createFailedError(NotImplementedError())) } @@ -48,21 +45,21 @@ class FakeOnrampSdkModule( override fun registerWalletAddress( walletAddress: String?, network: String?, - promise: Promise?, + promise: Promise? ) { promise?.resolve(createFailedError(NotImplementedError())) } override fun attachKycInfo( kycInfo: ReadableMap?, - promise: Promise?, + promise: Promise? ) { promise?.resolve(createFailedError(NotImplementedError())) } override fun updatePhoneNumber( phone: String?, - promise: Promise?, + promise: Promise? ) { promise?.resolve(createFailedError(NotImplementedError())) } @@ -78,7 +75,7 @@ class FakeOnrampSdkModule( override fun collectPaymentMethod( paymentMethod: String?, platformPayParams: ReadableMap?, - promise: Promise?, + promise: Promise? ) { promise?.resolve(createFailedError(NotImplementedError())) } @@ -93,14 +90,14 @@ class FakeOnrampSdkModule( override fun performCheckout( onrampSessionId: String?, - promise: Promise?, + promise: Promise? ) { promise?.resolve(createFailedError(NotImplementedError())) } override fun onrampAuthorize( linkAuthIntentId: String?, - promise: Promise?, + promise: Promise? ) { promise?.resolve(createFailedError(NotImplementedError())) } diff --git a/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt b/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt index bdd4cbd416..520d8b0c0d 100644 --- a/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +++ b/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt @@ -243,7 +243,7 @@ class StripeSdkModule( // Store the original ReadableMap for custom payment methods bundle.putSerializable( "customPaymentMethodConfigurationReadableMap", - customPaymentMethodConfig.toHashMap(), + customPaymentMethodConfig.toHashMap() ) } @@ -1400,8 +1400,7 @@ class StripeSdkModule( private fun setupComposeCompatView() { UiThreadUtil.runOnUiThread { composeCompatView = - composeCompatView ?: StripeAbstractComposeView - .CompatView(context = reactApplicationContext) + composeCompatView ?: StripeAbstractComposeView.CompatView(context = reactApplicationContext) .also { currentActivity?.findViewById(android.R.id.content)?.addView( it, diff --git a/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt b/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt index fe9541664a..621844ee5c 100644 --- a/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +++ b/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt @@ -28,11 +28,10 @@ class StripeSdkPackage : BaseReactPackage() { } override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { - val moduleList: Array> = - arrayOf( - StripeSdkModule::class.java, - getOnrampModuleClass(), - ) + val moduleList: Array> = arrayOf( + StripeSdkModule::class.java, + getOnrampModuleClass(), + ) val reactModuleInfoMap: MutableMap = HashMap() for (moduleClass in moduleList) { val reactModule = moduleClass.getAnnotation(ReactModule::class.java) ?: continue diff --git a/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt b/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt index 4de126973a..cf99f645f0 100644 --- a/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +++ b/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt @@ -178,9 +178,13 @@ internal fun createError( return mapError(code, error.message, error.localizedMessage, null, null, null) } -internal fun createCanceledError(message: String? = null): WritableMap = createError(ErrorType.Canceled.toString(), message) +internal fun createCanceledError(message: String? = null): WritableMap { + return createError(ErrorType.Canceled.toString(), message) +} -internal fun createFailedError(error: Throwable): WritableMap = createError(ErrorType.Failed.toString(), error) +internal fun createFailedError(error: Throwable): WritableMap { + return createError(ErrorType.Failed.toString(), error) +} internal fun createMissingInitError(): WritableMap = createError( diff --git a/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt b/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt index be5610e26a..3fc40c14c0 100644 --- a/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +++ b/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt @@ -30,7 +30,9 @@ import com.stripe.android.model.Token import com.stripe.android.paymentelement.ExperimentalCustomPaymentMethodsApi import com.stripe.android.paymentsheet.PaymentSheet -internal fun createEmptyResult(): WritableMap = WritableNativeMap() +internal fun createEmptyResult(): WritableMap { + return WritableNativeMap() +} internal fun createResult( key: String, @@ -559,7 +561,7 @@ internal fun mapNextAction( NextActionType.UseStripeSdk, NextActionType.UpiAwaitNotification, null, - -> { + -> { return null } NextActionType.DisplayBoletoDetails -> { @@ -678,7 +680,8 @@ internal fun mapToBillingDetails( return paymentMethodBillingDetailsBuilder.build() } -internal fun mapToMetadata(metadata: ReadableMap?): Map? = metadata?.toHashMap()?.mapValues { it.value.toString() } +internal fun mapToMetadata(metadata: ReadableMap?): Map? = + metadata?.toHashMap()?.mapValues { it.value.toString() } internal fun mapToShippingDetails(shippingDetails: ReadableMap?): ConfirmPaymentIntentParams.Shipping? { if (shippingDetails == null) { diff --git a/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt b/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt index f8afbd23a6..572765b165 100644 --- a/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt +++ b/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt @@ -179,11 +179,9 @@ class OnrampSdkModule( return } - val coordinator = - OnrampCoordinator - .Builder() - .build(application, SavedStateHandle()) - .also { this.onrampCoordinator = it } + val coordinator = OnrampCoordinator.Builder() + .build(application, SavedStateHandle()) + .also { this.onrampCoordinator = it } CoroutineScope(Dispatchers.IO).launch { val appearanceMap = config.getMap("appearance") @@ -196,12 +194,11 @@ class OnrampSdkModule( val displayName = config.getString("merchantDisplayName") ?: "" - val configuration = - OnrampConfiguration( - merchantDisplayName = displayName, - publishableKey = publishableKey, - appearance = appearance, - ) + val configuration = OnrampConfiguration( + merchantDisplayName = displayName, + publishableKey = publishableKey, + appearance = appearance + ) val configureResult = coordinator.configure(configuration) @@ -234,24 +231,23 @@ class OnrampSdkModule( return } - val onrampCallbacks = - OnrampCallbacks( - authenticateUserCallback = { result -> - handleOnrampAuthenticationResult(result, authenticateUserPromise!!) - }, - verifyIdentityCallback = { result -> - handleOnrampIdentityVerificationResult(result, identityVerificationPromise!!) - }, - collectPaymentCallback = { result -> - handleOnrampCollectPaymentResult(result, collectPaymentPromise!!) - }, - authorizeCallback = { result -> - handleOnrampAuthorizationResult(result, authorizePromise!!) - }, - checkoutCallback = { result -> - handleOnrampCheckoutResult(result, checkoutPromise!!) - }, - ) + val onrampCallbacks = OnrampCallbacks( + authenticateUserCallback = { result -> + handleOnrampAuthenticationResult(result, authenticateUserPromise!!) + }, + verifyIdentityCallback = { result -> + handleOnrampIdentityVerificationResult(result, identityVerificationPromise!!) + }, + collectPaymentCallback = { result -> + handleOnrampCollectPaymentResult(result, collectPaymentPromise!!) + }, + authorizeCallback = { result -> + handleOnrampAuthorizationResult(result, authorizePromise!!) + }, + checkoutCallback = { result -> + handleOnrampCheckoutResult(result, checkoutPromise!!) + } + ) try { onrampPresenter = onrampCoordinator!!.createPresenter(activity, onrampCallbacks) @@ -266,11 +262,10 @@ class OnrampSdkModule( email: String, promise: Promise, ) { - val coordinator = - onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { when (val result = coordinator.hasLinkAccount(email)) { is OnrampHasLinkAccountResult.Completed -> { @@ -288,19 +283,17 @@ class OnrampSdkModule( info: ReadableMap, promise: Promise, ) { - val coordinator = - onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { - val linkUserInfo = - LinkUserInfo( - email = info.getString("email") ?: "", - phone = info.getString("phone") ?: "", - country = info.getString("country") ?: "", - fullName = info.getString("fullName"), - ) + val linkUserInfo = LinkUserInfo( + email = info.getString("email") ?: "", + phone = info.getString("phone") ?: "", + country = info.getString("country") ?: "", + fullName = info.getString("fullName"), + ) val result = coordinator.registerLinkUser(linkUserInfo) when (result) { @@ -318,13 +311,12 @@ class OnrampSdkModule( override fun registerWalletAddress( walletAddress: String, network: String, - promise: Promise, + promise: Promise ) { - val coordinator = - onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { val cryptoNetwork = enumValues().firstOrNull { it.value == network } if (cryptoNetwork == null) { @@ -346,21 +338,20 @@ class OnrampSdkModule( @ReactMethod override fun attachKycInfo( kycInfo: ReadableMap, - promise: Promise, + promise: Promise ) { - val coordinator = - onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { val firstName = kycInfo.getString("firstName") if (firstName.isNullOrEmpty()) { promise.resolve( createError( ErrorType.Unknown.toString(), - "Missing required field: firstName", - ), + "Missing required field: firstName" + ) ) return@launch } @@ -369,8 +360,8 @@ class OnrampSdkModule( promise.resolve( createError( ErrorType.Unknown.toString(), - "Missing required field: lastName", - ), + "Missing required field: lastName" + ) ) return@launch } @@ -379,8 +370,8 @@ class OnrampSdkModule( promise.resolve( createError( ErrorType.Unknown.toString(), - "Missing required field: idNumber", - ), + "Missing required field: idNumber" + ) ) return@launch } @@ -396,39 +387,37 @@ class OnrampSdkModule( DateOfBirth( day = dateOfBirthMap.getInt("day"), month = dateOfBirthMap.getInt("month"), - year = dateOfBirthMap.getInt("year"), + year = dateOfBirthMap.getInt("year") ) } else { promise.resolve( createError( ErrorType.Unknown.toString(), - "Missing required field: dateOfBirth", - ), + "Missing required field: dateOfBirth" + ) ) return@launch } val addressMap = kycInfo.getMap("address") - val addressObj = - addressMap?.let { - PaymentSheet.Address( - city = it.getString("city"), - country = it.getString("country"), - line1 = it.getString("line1"), - line2 = it.getString("line2"), - postalCode = it.getString("postalCode"), - state = it.getString("state"), - ) - } ?: PaymentSheet.Address() - - val kycInfoObj = - KycInfo( - firstName = firstName, - lastName = lastName, - idNumber = idNumber, - dateOfBirth = dob, - address = addressObj, + val addressObj = addressMap?.let { + PaymentSheet.Address( + city = it.getString("city"), + country = it.getString("country"), + line1 = it.getString("line1"), + line2 = it.getString("line2"), + postalCode = it.getString("postalCode"), + state = it.getString("state"), ) + } ?: PaymentSheet.Address() + + val kycInfoObj = KycInfo( + firstName = firstName, + lastName = lastName, + idNumber = idNumber, + dateOfBirth = dob, + address = addressObj, + ) when (val result = coordinator.attachKycInfo(kycInfoObj)) { is OnrampAttachKycInfoResult.Completed -> { @@ -442,15 +431,11 @@ class OnrampSdkModule( } @ReactMethod - override fun updatePhoneNumber( - phone: String, - promise: Promise, - ) { - val coordinator = - onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + override fun updatePhoneNumber(phone: String, promise: Promise) { + val coordinator = onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { when (val result = coordinator.updatePhoneNumber(phone)) { OnrampUpdatePhoneNumberResult.Completed -> { @@ -465,11 +450,10 @@ class OnrampSdkModule( @ReactMethod override fun authenticateUser(promise: Promise) { - val presenter = - onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val presenter = onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } authenticateUserPromise = promise @@ -478,11 +462,10 @@ class OnrampSdkModule( @ReactMethod override fun verifyIdentity(promise: Promise) { - val presenter = - onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val presenter = onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } identityVerificationPromise = promise @@ -493,27 +476,25 @@ class OnrampSdkModule( override fun collectPaymentMethod( paymentMethod: String, platformPayParams: ReadableMap, - promise: Promise, + promise: Promise ) { - val presenter = - onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val presenter = onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } - val method = - when (paymentMethod) { - "Card" -> PaymentMethodType.Card - "BankAccount" -> PaymentMethodType.BankAccount - else -> { - promise.resolve( - createFailedError( - IllegalArgumentException("Unsupported payment method: $paymentMethod"), - ), + val method = when (paymentMethod) { + "Card" -> PaymentMethodType.Card + "BankAccount" -> PaymentMethodType.BankAccount + else -> { + promise.resolve( + createFailedError( + IllegalArgumentException("Unsupported payment method: $paymentMethod") ) - return - } + ) + return } + } collectPaymentPromise = promise @@ -522,11 +503,10 @@ class OnrampSdkModule( @ReactMethod override fun createCryptoPaymentToken(promise: Promise) { - val coordinator = - onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } CoroutineScope(Dispatchers.IO).launch { val result = coordinator.createCryptoPaymentToken() @@ -539,13 +519,12 @@ class OnrampSdkModule( @ReactMethod override fun performCheckout( onrampSessionId: String, - promise: Promise, + promise: Promise ) { - val presenter = - onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val presenter = onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } val checkoutHandler: suspend () -> String = { checkoutClientSecretDeferred = CompletableDeferred() @@ -569,22 +548,18 @@ class OnrampSdkModule( checkoutClientSecretDeferred?.complete(clientSecret) } else { checkoutClientSecretDeferred?.completeExceptionally( - RuntimeException("Failed to provide checkout client secret"), + RuntimeException("Failed to provide checkout client secret") ) } checkoutClientSecretDeferred = null } @ReactMethod - override fun onrampAuthorize( - linkAuthIntentId: String, - promise: Promise, - ) { - val presenter = - onrampPresenter ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + override fun onrampAuthorize(linkAuthIntentId: String, promise: Promise) { + val presenter = onrampPresenter ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } authorizePromise = promise @@ -593,11 +568,10 @@ class OnrampSdkModule( @ReactMethod override fun logout(promise: Promise) { - val coordinator = - onrampCoordinator ?: run { - promise.resolve(createOnrampNotConfiguredError()) - return - } + val coordinator = onrampCoordinator ?: run { + promise.resolve(createOnrampNotConfiguredError()) + return + } promise.resolve(createFailedError(NotImplementedError())) } @@ -673,10 +647,7 @@ class OnrampSdkModule( ) } - private fun handleOnrampAuthenticationResult( - result: OnrampAuthenticateResult, - promise: Promise, - ) { + private fun handleOnrampAuthenticationResult(result: OnrampAuthenticateResult, promise: Promise) { when (result) { is OnrampAuthenticateResult.Completed -> { promise.resolveString("customerId", result.customerId) @@ -692,7 +663,7 @@ class OnrampSdkModule( private fun handleOnrampIdentityVerificationResult( result: OnrampVerifyIdentityResult, - promise: Promise, + promise: Promise ) { when (result) { is OnrampVerifyIdentityResult.Completed -> { @@ -709,15 +680,14 @@ class OnrampSdkModule( private fun handleOnrampCollectPaymentResult( result: OnrampCollectPaymentMethodResult, - promise: Promise, + promise: Promise ) { when (result) { is OnrampCollectPaymentMethodResult.Completed -> { val displayData = Arguments.createMap() - val icon = - currentActivity - ?.let { ContextCompat.getDrawable(it, result.displayData.iconRes) } - ?.let { "data:image/png;base64," + getBase64FromBitmap(getBitmapFromDrawable(it)) } + val icon = currentActivity + ?.let { ContextCompat.getDrawable(it, result.displayData.iconRes) } + ?.let { "data:image/png;base64," + getBase64FromBitmap(getBitmapFromDrawable(it)) } displayData.putString("icon", icon) displayData.putString("label", result.displayData.label) result.displayData.sublabel?.let { displayData.putString("sublabel", it) } @@ -732,24 +702,21 @@ class OnrampSdkModule( } } - private fun handleOnrampAuthorizationResult( - result: OnrampAuthorizeResult, - promise: Promise, - ) { + private fun handleOnrampAuthorizationResult(result: OnrampAuthorizeResult, promise: Promise) { when (result) { is OnrampAuthorizeResult.Consented -> { promise.resolve( WritableNativeMap().apply { putString("status", "Consented") putString("customerId", result.customerId) - }, + } ) } is OnrampAuthorizeResult.Denied -> { promise.resolve( WritableNativeMap().apply { putString("status", "Denied") - }, + } ) } is OnrampAuthorizeResult.Canceled -> { @@ -761,10 +728,7 @@ class OnrampSdkModule( } } - private fun handleOnrampCheckoutResult( - result: OnrampCheckoutResult, - promise: Promise, - ) { + private fun handleOnrampCheckoutResult(result: OnrampCheckoutResult, promise: Promise) { when (result) { is OnrampCheckoutResult.Completed -> { promise.resolveVoid() @@ -780,7 +744,7 @@ class OnrampSdkModule( private fun handleOnrampCreateCryptoPaymentTokenResult( result: OnrampCreateCryptoPaymentTokenResult, - promise: Promise, + promise: Promise ) { when (result) { is OnrampCreateCryptoPaymentTokenResult.Completed -> { @@ -796,17 +760,11 @@ class OnrampSdkModule( resolve(createEmptyResult()) } - private fun Promise.resolveString( - key: String, - value: String, - ) { + private fun Promise.resolveString(key: String, value: String) { resolve(WritableNativeMap().apply { putString(key, value) }) } - private fun Promise.resolveBoolean( - key: String, - value: Boolean, - ) { + private fun Promise.resolveBoolean(key: String, value: Boolean) { resolve(WritableNativeMap().apply { putBoolean(key, value) }) } }