Skip to content
Merged
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

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.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)


Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,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 @@ -111,6 +107,9 @@ 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");
```

## Debug / Contribution
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+' // From node_modules
implementation 'com.smallcase.gateway:sdk:6.1.2'
implementation 'com.smallcase.gateway:sdk:6.1.3'
implementation 'com.smallcase.loans:sdk:5.3.2'
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

2 changes: 1 addition & 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.7.0",
"version": "7.7.1",
"description": "smallcase gateway bindings for react native",
"main": "src/index.js",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion react-native-smallcase-gateway.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ Pod::Spec.new do |s|
s.dependency "ReactCommon/turbomodule/core"
end

s.dependency 'SCGateway', '7.2.0'
s.dependency 'SCGateway', '7.2.1'
s.dependency 'SCLoans', '7.4.0'
end
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
16 changes: 8 additions & 8 deletions smart_investing_react_native/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1410,14 +1410,14 @@ PODS:
- Yoga
- react-native-segmented-control (2.5.7):
- React-Core
- react-native-smallcase-gateway (7.4.3):
- react-native-smallcase-gateway (7.6.2):
- RCTRequired
- RCTTypeSafety
- React-Codegen
- React-Core
- ReactCommon/turbomodule/core
- SCGateway (= 7.2.0)
- SCLoans (= 7.3.0)
- SCGateway (= 7.2.1)
- SCLoans (= 7.4.0)
- React-NativeModulesApple (0.79.4):
- glog
- hermes-engine
Expand Down Expand Up @@ -1839,8 +1839,8 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- SCGateway (7.2.0)
- SCLoans (7.3.0)
- SCGateway (7.2.1)
- SCLoans (7.4.0)
- SocketRocket (0.7.1)
- Yoga (0.0.0)

Expand Down Expand Up @@ -2128,7 +2128,7 @@ SPEC CHECKSUMS:
React-microtasksnativemodule: ef2292ca147fa8793305e4693586ad0caf3afad3
react-native-safe-area-context: 562163222d999b79a51577eda2ea8ad2c32b4d06
react-native-segmented-control: bf6e0032726727498e18dd437ae88afcdbc18e99
react-native-smallcase-gateway: 12d3338564d2781ee8be7de425265c47646fa7c6
react-native-smallcase-gateway: 799618640439c348253f939cc7743818b5502184
React-NativeModulesApple: da60186ad0aafff031a9bc86b048711d34acc813
React-oscompat: 472a446c740e39ee39cd57cd7bfd32177c763a2b
React-perflogger: bbca3688c62f4f39e972d6e21969c95fe441fb6c
Expand Down Expand Up @@ -2163,8 +2163,8 @@ SPEC CHECKSUMS:
RNCClipboard: 37de6995ef72dc869422879e51a46a520d3f08b3
RNGestureHandler: ebef699ea17e7c0006c1074e1e423ead60ce0121
RNScreens: 3f6e41f9f89cb888a6b4b27566bdfdf7a3bf51ad
SCGateway: 8089d79c55ecc8e7b581e0bf56fd28a2e3d957d0
SCLoans: 1effcdedc4be32992f5a1a08afa2b812827e5086
SCGateway: c18f47d4ae5df3d0189a8b6dbdf7f3503c9f07dc
SCLoans: 87d86efe22a858a151290fb919ad3a7a069c3db3
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: a6cb833e04fb8c59a012b49fb1d040fcb0cbb633

Expand Down
2 changes: 1 addition & 1 deletion smart_investing_react_native/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6230,7 +6230,7 @@ react-native-screens@4.17.1:
warn-once "^0.1.0"

"react-native-smallcase-gateway@file:..":
version "7.4.3"
version "7.6.2"
dependencies:
standard-version "^9.5.0"

Expand Down
17 changes: 17 additions & 0 deletions src/SmallcaseGateway.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,22 @@ const launchSmallplug = async (targetEndpoint, params) => {
return SmallcaseGatewayNative.launchSmallplug(safeEndpoint, safeParams);
};

/**
* Launches a standalone native WebView for an absolute HTTP(S) URL.
* Gateway setup and initialization are not required.
*
* @param {string} url
* @returns {Promise<boolean>} resolves when the WebView launch is accepted
*/
const launchScWebView = async (url) => {
const safeUrl = typeof url === 'string' ? url.trim() : '';
if (!/^https?:\/\/.+/i.test(safeUrl)) {
throw new TypeError('A valid absolute HTTP(S) URL is required');
}

return SmallcaseGatewayNative.launchScWebView(safeUrl);
};

/**
* launches smallcases module
* On success, resolves with SmallplugRes.
Expand Down Expand Up @@ -302,6 +318,7 @@ const SmallcaseGateway = {
triggerTransaction,
triggerMfTransaction,
setConfigEnvironment,
launchScWebView,
launchSmallplug,
launchSmallplugWithBranding,
getSdkVersion,
Expand Down
1 change: 1 addition & 0 deletions src/__mocks__/react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const NativeModules = {
init: jest.fn(),
triggerLeadGen: jest.fn(),
triggerTransaction: jest.fn(),
launchScWebView: jest.fn(),
setConfigEnvironment: jest.fn(),
setHybridSdkVersion: jest.fn(),
},
Expand Down
20 changes: 20 additions & 0 deletions src/__tests__/launchScWebView.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
jest.mock('react-native');

import SmallcaseGateway from '../index';
import { NativeModules } from 'react-native';

describe('launchScWebView', () => {
test('launches an absolute HTTP(S) URL', async () => {
await SmallcaseGateway.launchScWebView('https://www.smallcase.com');

expect(NativeModules.SmallcaseGateway.launchScWebView).toHaveBeenCalledWith(
'https://www.smallcase.com'
);
});

test('rejects an invalid URL before invoking native', async () => {
await expect(
SmallcaseGateway.launchScWebView('smallcase.com')
).rejects.toThrow('A valid absolute HTTP(S) URL is required');
});
});
6 changes: 6 additions & 0 deletions types/SmallcaseGateway.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ declare namespace SmallcaseGateway {
export { triggerTransaction };
export { triggerMfTransaction };
export { setConfigEnvironment };
export { launchScWebView };
export { launchSmallplug };
export { launchSmallplugWithBranding };
export { getSdkVersion };
Expand Down Expand Up @@ -157,6 +158,11 @@ declare function triggerMfTransaction(transactionId: string): Promise<transactio
* @param {envConfig} envConfig
*/
declare function setConfigEnvironment(envConfig: envConfig): any;
/**
* Launches a standalone native WebView for an absolute HTTP(S) URL.
* Gateway setup and initialization are not required.
*/
declare function launchScWebView(url: string): Promise<boolean>;
/**
* launches smallcases module
*
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ declare const _default: {
triggerTransaction: (transactionId: string, utmParams?: any, brokerList?: string[]) => Promise<import("./SmallcaseGateway").transactionRes>;
triggerMfTransaction: (transactionId: string) => Promise<import("./SmallcaseGateway").transactionRes>;
setConfigEnvironment: (envConfig: import("./SmallcaseGateway").envConfig) => any;
launchScWebView: (url: string) => Promise<boolean>;
launchSmallplug: (targetEndpoint: string, params: string) => unknown;
launchSmallplugWithBranding: (targetEndpoint: string, params: string, headerColor: string, headerOpacity: number, backIconColor: string, backIconOpacity: number) => unknown;
getSdkVersion: () => Promise;
Expand Down
Loading