Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,58 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [7.7.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.7.1...v7.7.2) (2026-09-23)

### Improvements

* update Android Gateway SDK to 6.1.4 and Loans SDK to 5.4.0
* update iOS Gateway SDK to 7.2.2 and Loans SDK to 7.5.0

### [7.7.1](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.7.0...v7.7.1) (2026-09-20)


### Features

* expose webview-as-a-service ([648f235](https://github.com/smallcase/react-native-smallcase-gateway/commit/648f2359715094ce88f680e3ba18fc2c7cfbae4c))

## [7.7.0](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.6.2...v7.7.0) (2026-08-27)


### Features

* add Loans KYC permission usage descriptions ([e384009](https://github.com/smallcase/react-native-smallcase-gateway/commit/e384009584353f89528e07bbf7ee28ce7e2eba2d))

### [7.6.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.6.1...v7.6.2) (2026-09-02)

### [7.6.1](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.6.0...v7.6.1) (2026-08-17)

### Improvements

* **android:** update Loans SDK to 5.3.1

## [7.6.0](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.5.0...v7.6.0) (2026-07-31)


### Improvements

* **android:** update Loans SDK to 5.3.0

### Bug Fixes

* **android:** keep SCGateway classes for R8 ([e99d428](https://github.com/smallcase/react-native-smallcase-gateway/commit/e99d4284368827051a46a68f12e2dba75852ac3e))

## [7.5.0](https://npmjs.com/package/react-native-smallcase-gateway/v/7.5.0?activeTab=versions) (2026-07-10)

Dev Improvements

* Bumped Loans native SDK to the dark-theme internal release (Android 5.1.4-92, iOS 7.1.2-44) and dropped a stale ProGuard workaround while keeping R8 full mode on.

Features

* Added a `colorScheme` (`dark` / `light` / `system`) option to `ScLoanInfo`, letting partner apps control the LAS web UI theme instead of always defaulting to light.

### [7.4.4](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.4.3...v7.4.4) (2026-06-11)

### [7.4.3](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.4.0...v7.4.3) (2026-06-09)

### [7.4.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v7.4.0...v7.4.2) (2026-05-25)
Expand Down
33 changes: 27 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ platform :ios, '11.0'
then run
`cd ios; pod update`

Apps using Loans KYC must also add these usage descriptions to the iOS app's `Info.plist`:

```xml
<key>NSCameraUsageDescription</key>
<string>Camera access is required to capture your selfie during KYC.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access is required for audio during video KYC.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location access is required to verify your location during KYC.</string>
```

## android setup

Add these lines to your project level `build.gradle`
Expand All @@ -37,12 +48,8 @@ allprojects {
repositories {
// .. you other repositories
maven {
url "http://artifactory.smallcase.com/artifactory/gradle-dev-local"
credentials {
username "react_native_user"
password "reactNativeUser123"
}
}
url "https://artifactory.smallcase.com/artifactory/SCGateway"
}
}
}
```
Expand Down Expand Up @@ -100,8 +107,22 @@ const res = await SmallcaseGateway.triggerTransaction(transactionId);

// start lead generation flow
SmallcaseGateway.triggerLeadGen({ email: "test@gmail.com" });

// launch a standalone WebView; setup/init are not required
await SmallcaseGateway.launchScWebView("https://www.smallcase.com");
```

## Native SDK debug mode

The native Gateway and Loans SDK versions this package depends on are pinned in `native-sdk.json`, once for `release` (default) and once for `debug`. Debug builds of the native SDKs enable WebView inspection and debug logging, and are published to smallcase's internal registries only.

To consume the debug builds:

- Android: add `SmallcaseGateway_sdkMode=debug` to the host app's `android/gradle.properties`, then sync. Artifactory access to `SCGateway-internal` is required.
- iOS: add `source 'git@github.com:smallcase/cocoapodspec-internal.git'` and `source 'https://cdn.cocoapods.org/'` to the host app's `Podfile`, then run `SMALLCASE_SDK_MODE=debug pod install`. Run a plain `pod install` to switch back.

The build fails with an explicit error if debug mode is selected but `native-sdk.json` has no debug pin for an SDK.

## Debug / Contribution

Make sure you have react native dev environment set up
Expand Down
18 changes: 16 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,25 @@ repositories {

def kotlin_version = getExtOrDefault('kotlinVersion')

// Native SDK pins live in native-sdk.json. Set SmallcaseGateway_sdkMode=debug in the
// host app's gradle.properties to consume debug builds of the native SDKs.
def sdkMode = getExtOrDefault('sdkMode') ?: 'release'
def nativeSdks = new groovy.json.JsonSlurper().parse(file("$projectDir/../native-sdk.json"))
if (!nativeSdks.containsKey(sdkMode)) {
throw new GradleException("${project.name}: unknown SmallcaseGateway_sdkMode '${sdkMode}', expected one of ${nativeSdks.keySet()}")
}
def androidSdks = nativeSdks[sdkMode].android
androidSdks.each { sdk, coordinate ->
if (!coordinate) {
throw new GradleException("${project.name}: no ${sdk} SDK pinned for mode '${sdkMode}' in native-sdk.json")
}
}

dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+' // From node_modules
implementation 'com.smallcase.gateway:sdk:6.1.1'
implementation 'com.smallcase.loans:sdk-sourav-native-dark-theme-cb54bf9:5.1.4-92-release'
implementation androidSdks.gateway
implementation androidSdks.loans
implementation "androidx.core:core-ktx:1.3.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.reactnativesmallcasegateway

import android.net.Uri
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.facebook.react.bridge.*
Expand Down Expand Up @@ -163,6 +164,28 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
}
}

@ReactMethod
fun launchScWebView(url: String, promise: Promise) {
val activity = reactApplicationContext.currentActivity ?: run {
promise.reject("no_activity", "No active Android activity")
return
}
val uri = Uri.parse(url)
if (uri.scheme?.lowercase() !in setOf("http", "https") || uri.host.isNullOrBlank()) {
promise.reject("invalid_url", "A valid absolute HTTP(S) URL is required")
return
}

activity.runOnUiThread {
try {
SmallcaseGatewaySdk.launchScWebView(activity, url)
promise.resolve(true)
} catch (error: Exception) {
promise.reject("launch_failed", error)
}
}
}

@ReactMethod
fun launchSmallplug(targetEndpoint: String, params: String, promise: Promise) {

Expand Down Expand Up @@ -562,4 +585,3 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
}

}

22 changes: 21 additions & 1 deletion ios/SmallcaseGateway.m
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,27 @@ @interface RCT_EXTERN_MODULE(SmallcaseGateway, NSObject)
}

//MARK: smallplug
RCT_REMAP_METHOD(launchScWebView,
urlString:(NSString *)urlString
launchScWebViewWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSURL *url = [NSURL URLWithString:urlString];
NSString *scheme = url.scheme.lowercaseString;
if (url == nil || url.host.length == 0 ||
!([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"])) {
reject(@"invalid_url", @"A valid absolute HTTP(S) URL is required", nil);
return;
}

dispatch_async(dispatch_get_main_queue(), ^{
[SCGateway.shared
launchScWebViewWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController]
url:url
completion:^(__unused id response, __unused NSError *error) {}];
resolve(@(YES));
});
}

RCT_REMAP_METHOD(launchSmallplug,
targetEndpoint:(NSString *)targetEndpoint
params:(NSString *)params
Expand Down Expand Up @@ -809,4 +830,3 @@ - (NSError *)scLoanErrorToDict:(ScLoanError *)error {
}

@end

22 changes: 22 additions & 0 deletions native-sdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"release": {
"android": {
"gateway": "com.smallcase.gateway:sdk:6.1.4",
"loans": "com.smallcase.loans:sdk:5.4.0"
},
"ios": {
"gateway": { "name": "SCGateway", "version": "7.2.2" },
"loans": { "name": "SCLoans", "version": "7.5.0" }
}
},
"debug": {
"android": {
"gateway": null,
"loans": null
},
"ios": {
"gateway": null,
"loans": null
}
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-native-smallcase-gateway",
"title": "React Native Smallcase Gateway",
"version": "7.4.3",
"version": "7.7.2",
"description": "smallcase gateway bindings for react native",
"main": "src/index.js",
"files": [
Expand All @@ -12,6 +12,7 @@
"cpp",
"types",
"react-native-smallcase-gateway.podspec",
"native-sdk.json",
"!lib/typescript/example",
"!lib/typescript/smart_investing_react_native",
"!android/build",
Expand Down
18 changes: 14 additions & 4 deletions react-native-smallcase-gateway.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

# Native SDK pins live in native-sdk.json. Run `SMALLCASE_SDK_MODE=debug pod install`
# in the host app to consume debug builds of the native SDKs.
native_sdks = JSON.parse(File.read(File.join(__dir__, "native-sdk.json")))
sdk_mode = ENV.fetch("SMALLCASE_SDK_MODE", "release")
unless native_sdks.key?(sdk_mode)
raise "react-native-smallcase-gateway: unknown SMALLCASE_SDK_MODE '#{sdk_mode}', expected one of #{native_sdks.keys}"
end
ios_sdks = native_sdks[sdk_mode]["ios"]
ios_sdks.each do |sdk, pod|
raise "react-native-smallcase-gateway: no #{sdk} SDK pinned for mode '#{sdk_mode}' in native-sdk.json" if pod.nil?
end
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'

Pod::Spec.new do |s|
Expand Down Expand Up @@ -34,8 +46,6 @@ Pod::Spec.new do |s|
s.dependency "ReactCommon/turbomodule/core"
end

s.dependency 'SCGateway', '7.2.0'
# INTERNAL TEST PIN: dark-theme branch build (mirrors the android/build.gradle pin).
# Revert to: s.dependency 'SCLoans', '7.2.0'
s.dependency 'SCLoans-sourav-native-dark-theme-37c97d9', '7.1.2-45-release'
s.dependency ios_sdks["gateway"]["name"], ios_sdks["gateway"]["version"]
s.dependency ios_sdks["loans"]["name"], ios_sdks["loans"]["version"]
end
2 changes: 2 additions & 0 deletions smart_investing_react_native/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# SCGateway proguard rules — keeping it here, same as loans.
-keep class com.smallcase.gateway.** { *; }

-keep class com.example.** { *; }

# Retrofit + R8 full mode (AGP 8 default): generic signatures are stripped for
# any type that is not kept, so ConfigService.getBrokerConfigs(): Call<Foo>
# degrades to a raw Call and Retrofit rejects it
Expand Down
3 changes: 0 additions & 3 deletions smart_investing_react_native/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,3 @@ hermesEnabled=true
artifactory_contextUrl=https\://artifactory.smallcase.com/artifactory
artifactory_password=reactNativeUser123
artifactory_user=react_native_user

# R8 full mode enabled — verified safe against loans SDK consumer-rules.pro
android.enableR8.fullMode=true
30 changes: 26 additions & 4 deletions smart_investing_react_native/app/screens/SmtScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React from 'react';
import {Button, TextInput, View} from 'react-native';
import {Button, ScrollView, TextInput} from 'react-native';
import {launchSmallPlug} from '../apis/Functions';
import {SCGatewayEventManager} from 'react-native-smallcase-gateway';
import SmallcaseGateway, {
SCGatewayEventManager,
} from 'react-native-smallcase-gateway';

const SmtScreen = () => {
const [webViewUrl, onChangeWebViewUrl] = React.useState(
'https://www.smallcase.com',
);
const [targetEndpoint, onChangeTargetEndpoint] = React.useState<
string | null
>(null);
Expand All @@ -21,7 +26,7 @@ const SmtScreen = () => {
string | null
>(null);
return (
<View>
<ScrollView>
<TextInput
placeholder="Enter target end point"
onChange={event => {
Expand Down Expand Up @@ -99,7 +104,24 @@ const SmtScreen = () => {
title={'SmallPlug'}
accessibilityLabel="Learn more about this purple button"
/>
</View>
<TextInput
value={webViewUrl}
placeholder="Enter WebView URL"
autoCapitalize="none"
keyboardType="url"
onChangeText={onChangeWebViewUrl}
/>
<Button
title="Launch SC WebView"
onPress={async () => {
try {
await SmallcaseGateway.launchScWebView(webViewUrl);
} catch (error) {
console.error('SC WebView launch failed:', error);
}
}}
/>
</ScrollView>
);
};

Expand Down
Loading
Loading