Skip to content

Commit e3b5e2e

Browse files
authored
[SELF-698] scaffold mobile sdk demo app (#993)
* chore: scaffold mobile sdk demo app * test: cover demo app menu * prettier and types * sort * add android app foundation * fix android loading * get ios app running * update script * cr feedback * disable fabric * fixes * fixes * fix
1 parent c895396 commit e3b5e2e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3668
-530
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Mobile SDK Demo CI
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "packages/mobile-sdk-alpha/demo-app/**"
7+
- ".github/workflows/mobile-sdk-demo-ci.yml"
8+
- ".github/actions/**"
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- name: Setup Node
16+
uses: actions/setup-node@v4
17+
with:
18+
node-version-file: .nvmrc
19+
- name: Install Dependencies
20+
uses: ./.github/actions/yarn-install
21+
- name: Run demo app tests
22+
run: |
23+
yarn workspace demo-app test
24+
- name: Build demo app
25+
run: |
26+
yarn workspace demo-app build

app/metro.config.cjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ const extraNodeModules = {
1818
util: require.resolve('util'),
1919
assert: require.resolve('assert'),
2020
'@babel/runtime': path.join(trueMonorepoNodeModules, '@babel/runtime'),
21+
// Pin React and React Native to monorepo root
22+
react: path.join(trueMonorepoNodeModules, 'react'),
23+
'react-native': path.join(trueMonorepoNodeModules, 'react-native'),
2124
'@': path.join(__dirname, 'src'),
2225
'@selfxyz/common': path.resolve(commonPath, 'dist'),
2326
'@selfxyz/mobile-sdk-alpha': path.resolve(sdkAlphaPath, 'dist'),

package.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"packages/*",
99
"prover/tests",
1010
"sdk/*",
11-
"scripts/tests"
11+
"scripts/tests",
12+
"packages/mobile-sdk-alpha/demo-app"
1213
],
1314
"scripts": {
1415
"build": "yarn workspaces foreach --topological-dev --parallel --exclude @selfxyz/contracts -i --all run build",
@@ -29,7 +30,15 @@
2930
},
3031
"resolutions": {
3132
"@typescript-eslint/eslint-plugin": "^8.39.0",
32-
"@typescript-eslint/parser": "^8.39.0"
33+
"@typescript-eslint/parser": "^8.39.0",
34+
"@babel/core": "^7.28.3",
35+
"@babel/runtime": "^7.28.3",
36+
"react": "^18.3.1",
37+
"react-native": "0.76.9"
38+
},
39+
"dependencies": {
40+
"react": "^18.3.1",
41+
"react-native": "0.76.9"
3342
},
3443
"devDependencies": {
3544
"@types/node": "^22.0.0",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
demo-app/**
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
dist
22
node_modules
3+
demo-app/android
4+
demo-app/ios

packages/mobile-sdk-alpha/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,22 @@ describe('Real mobile-sdk-alpha Integration', () => {
109109
- `npm run validate:exports` — ensure named exports only.
110110
- `npm run validate:pkg` — check packaging and export conditions.
111111
- `npm run report:exports` — output current public symbols.
112+
113+
## Self Demo App
114+
115+
The Self Demo App is a lightweight React Native playground in [`demo-app`](./demo-app).
116+
117+
```bash
118+
# start Metro bundler
119+
yarn workspace demo-app start
120+
121+
# type-check
122+
yarn workspace demo-app build
123+
124+
# run tests
125+
yarn workspace demo-app test
126+
127+
# or via package scripts
128+
cd packages/mobile-sdk-alpha
129+
yarn run:demo
130+
```
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# React Native
5+
.expo/
6+
.expo-shared/
7+
8+
# iOS
9+
ios/build/
10+
ios/DerivedData/
11+
ios/Pods/
12+
ios/*.xcworkspace/xcuserdata/
13+
ios/*.xcodeproj/xcuserdata/
14+
ios/*.xcodeproj/project.xcworkspace/xcuserdata/
15+
*.ipa
16+
17+
# Android
18+
android/app/build/
19+
android/app/.cxx/
20+
android/build/
21+
android/.gradle/
22+
android/gradle/
23+
android/gradlew
24+
android/gradlew.bat
25+
android/local.properties
26+
*.apk
27+
*.aab
28+
29+
# Metro
30+
.metro-health-check*
31+
32+
# Debug
33+
npm-debug.*
34+
yarn-debug.*
35+
yarn-error.*
36+
37+
# macOS
38+
.DS_Store
39+
40+
# Temporary files
41+
*.tmp
42+
*.temp
43+
44+
# Logs
45+
logs/
46+
*.log
47+
48+
# IDE
49+
.vscode/
50+
.idea/
51+
52+
# Yarn
53+
.yarn/cache
54+
.yarn/unplugged
55+
.yarn/build-state.yml
56+
.yarn/install-state.gz
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
2+
// SPDX-License-Identifier: BUSL-1.1
3+
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
4+
5+
import React from 'react';
6+
import { StyleSheet, Text, View } from 'react-native';
7+
8+
function App() {
9+
return (
10+
<View style={styles.container}>
11+
<Text style={styles.title}>Self Demo App</Text>
12+
<Text style={styles.item}>Register Document</Text>
13+
<Text style={styles.item}>Generate Mock</Text>
14+
<Text style={styles.item}>Prove QR Code</Text>
15+
</View>
16+
);
17+
}
18+
19+
const styles = StyleSheet.create({
20+
container: {
21+
flex: 1,
22+
justifyContent: 'center',
23+
alignItems: 'center',
24+
backgroundColor: '#fff',
25+
},
26+
title: {
27+
fontSize: 20,
28+
marginBottom: 12,
29+
fontWeight: 'bold',
30+
},
31+
item: {
32+
fontSize: 16,
33+
marginVertical: 4,
34+
},
35+
});
36+
37+
export default App;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
2+
// SPDX-License-Identifier: BUSL-1.1
3+
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
4+
5+
import React from 'react';
6+
import renderer from 'react-test-renderer';
7+
import { Text } from 'react-native';
8+
import App from '../App';
9+
10+
test('renders menu items', () => {
11+
const rendered = renderer.create(<App />);
12+
const texts = rendered.root.findAllByType(Text).map(node => React.Children.toArray(node.props.children).join(''));
13+
const expected = ['Self Demo App', 'Register Document', 'Generate Mock', 'Prove QR Code'];
14+
expect(texts).toEqual(expect.arrayContaining(expected));
15+
expect(texts).toHaveLength(expected.length);
16+
rendered.unmount();
17+
});
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
apply plugin: "com.android.application"
2+
apply plugin: "org.jetbrains.kotlin.android"
3+
apply plugin: "com.facebook.react"
4+
5+
/**
6+
* This is the configuration block to customize your React Native Android app.
7+
* By default you don't need to apply any configuration, just uncomment the lines you need.
8+
*/
9+
react {
10+
/* Folders */
11+
// The root of your project, i.e. where "package.json" lives. Default is '../..'
12+
root = file("../../../")
13+
// The folder where the react-native NPM package is. Default is ../../node_modules/react-native
14+
reactNativeDir = file("../../../node_modules/react-native")
15+
// The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
16+
codegenDir = file("../../../node_modules/@react-native/codegen")
17+
// The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
18+
cliFile = file("../../../node_modules/react-native/cli.js")
19+
20+
/* Variants */
21+
// The list of variants to that are debuggable. For those we're going to
22+
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
23+
// If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
24+
// debuggableVariants = ["liteDebug", "prodDebug"]
25+
26+
/* Bundling */
27+
// A list containing the node command and its flags. Default is just 'node'.
28+
// nodeExecutableAndArgs = ["node"]
29+
//
30+
// The command to run when bundling. By default is 'bundle'
31+
// bundleCommand = "ram-bundle"
32+
//
33+
// The path to the CLI configuration file. Default is empty.
34+
// bundleConfig = file(../rn-cli.config.js)
35+
//
36+
// The name of the generated asset file containing your JS bundle
37+
// bundleAssetName = "MyApplication.android.bundle"
38+
//
39+
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
40+
// entryFile = file("../js/MyApplication.android.js")
41+
//
42+
// A list of extra flags to pass to the 'bundle' commands.
43+
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
44+
// extraPackagerArgs = []
45+
46+
/* Hermes Commands */
47+
// The hermes compiler command to run. By default it is 'hermesc'
48+
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
49+
//
50+
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
51+
// hermesFlags = ["-O", "-output-source-map"]
52+
53+
/* Autolinking */
54+
autolinkLibrariesWithApp()
55+
}
56+
57+
/**
58+
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
59+
*/
60+
def enableProguardInReleaseBuilds = false
61+
62+
/**
63+
* The preferred build flavor of JavaScriptCore (JSC)
64+
*
65+
* For example, to use the international variant, you can use:
66+
* `def jscFlavor = io.github.react-native-community:jsc-android-intl:2026004.+`
67+
*
68+
* The international variant includes ICU i18n library and necessary data
69+
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
70+
* give correct results when using with locales other than en-US. Note that
71+
* this variant is about 6MiB larger per architecture than default.
72+
*/
73+
def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
74+
75+
android {
76+
ndkVersion rootProject.ext.ndkVersion
77+
buildToolsVersion rootProject.ext.buildToolsVersion
78+
compileSdk rootProject.ext.compileSdkVersion
79+
80+
namespace "com.selfdemoapp"
81+
defaultConfig {
82+
applicationId "com.selfdemoapp"
83+
minSdkVersion rootProject.ext.minSdkVersion
84+
targetSdkVersion rootProject.ext.targetSdkVersion
85+
versionCode 1
86+
versionName "1.0"
87+
}
88+
signingConfigs {
89+
debug {
90+
storeFile file('debug.keystore')
91+
storePassword 'android'
92+
keyAlias 'androiddebugkey'
93+
keyPassword 'android'
94+
}
95+
}
96+
buildTypes {
97+
debug {
98+
signingConfig signingConfigs.debug
99+
}
100+
release {
101+
// Caution! In production, you need to generate your own keystore file.
102+
// see https://reactnative.dev/docs/signed-apk-android.
103+
signingConfig signingConfigs.debug
104+
minifyEnabled enableProguardInReleaseBuilds
105+
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
106+
}
107+
}
108+
}
109+
110+
dependencies {
111+
// The version of react-native is set by the React Native Gradle Plugin
112+
implementation("com.facebook.react:react-android")
113+
114+
if (hermesEnabled.toBoolean()) {
115+
implementation("com.facebook.react:hermes-android")
116+
} else {
117+
implementation jscFlavor
118+
}
119+
}

0 commit comments

Comments
 (0)