Skip to content

Commit

Permalink
[Issue-281]: Implement Wallet Connect
Browse files Browse the repository at this point in the history
  • Loading branch information
dominhquang committed Aug 1, 2023
1 parent 5d13827 commit f259cd2
Show file tree
Hide file tree
Showing 62 changed files with 849 additions and 244 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import app.subwallet.mobile.nativeModules.RCTMinimizerPackage;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {
Expand All @@ -26,6 +27,7 @@ protected List<ReactPackage> getPackages() {
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new RCTMinimizerPackage());
return packages;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package app.subwallet.mobile.nativeModules;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import android.util.Log;

public class RCTMinimizer extends ReactContextBaseJavaModule {
private ReactApplicationContext reactContext;
RCTMinimizer(ReactApplicationContext context) {
super(context);
this.reactContext = reactContext;
}

@Override
public String getName() {
return "Minimizer";
}

@ReactMethod
public void goBack() {
android.app.Activity activity = getCurrentActivity();
if (activity != null) {
activity.moveTaskToBack(true);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package app.subwallet.mobile.nativeModules;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class RCTMinimizerPackage implements ReactPackage {

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}

@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();

modules.add(new RCTMinimizer(reactContext));

return modules;
}

}
6 changes: 3 additions & 3 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -824,10 +824,10 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234
boost: 57d2868c099736d80fcd648bf211b4431e51a558
BVLinearGradient: 612a04ff38e8480291f3379ee5b5a2c571f03fe0
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: 4eb7ee83e8d0ad7e20a829485295ff48823c4e4c
FBReactNativeSpec: b24809f97ae83c786928d56b732957195b4fa390
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
Expand All @@ -841,7 +841,7 @@ SPEC CHECKSUMS:
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4
glog: 476ee3e89abb49e07f822b48323c51c57124b572
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: b60ebc812e0179a612d8146ac54730d533c804a2
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
Expand Down
22 changes: 22 additions & 0 deletions ios/SubWalletMobile.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
0C80B921A6F3F58F76C31292 /* libPods-SubWalletMobile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-SubWalletMobile.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
355FCA172A72335100B34579 /* RCTMinimizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 355FCA152A72335100B34579 /* RCTMinimizer.m */; };
3577831F29CEA0080036830D /* fonts in Resources */ = {isa = PBXBuildFile; fileRef = 3577831E29CEA0080036830D /* fonts */; };
7699B88040F8A987B510C191 /* libPods-SubWalletMobile-SubWalletMobileTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-SubWalletMobile-SubWalletMobileTests.a */; };
81AB9BB82411601600AC10FF /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* SplashScreen.storyboard */; };
Expand Down Expand Up @@ -40,6 +41,8 @@
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = SubWalletMobile/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = SubWalletMobile/main.m; sourceTree = "<group>"; };
19F6CBCC0A4E27FBF8BF4A61 /* libPods-SubWalletMobile-SubWalletMobileTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SubWalletMobile-SubWalletMobileTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
355FCA152A72335100B34579 /* RCTMinimizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTMinimizer.m; path = SubWalletMobile/NativeModules/RCTMinimizer/RCTMinimizer.m; sourceTree = "<group>"; };
355FCA162A72335100B34579 /* RCTMinimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTMinimizer.h; path = SubWalletMobile/NativeModules/RCTMinimizer/RCTMinimizer.h; sourceTree = "<group>"; };
3577831E29CEA0080036830D /* fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = fonts; sourceTree = "<group>"; };
3B4392A12AC88292D35C810B /* Pods-SubWalletMobile.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SubWalletMobile.debug.xcconfig"; path = "Target Support Files/Pods-SubWalletMobile/Pods-SubWalletMobile.debug.xcconfig"; sourceTree = "<group>"; };
5709B34CF0A7D63546082F79 /* Pods-SubWalletMobile.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SubWalletMobile.release.xcconfig"; path = "Target Support Files/Pods-SubWalletMobile/Pods-SubWalletMobile.release.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -94,6 +97,7 @@
13B07FAE1A68108700A75B9A /* SubWalletMobile */ = {
isa = PBXGroup;
children = (
355FCA132A7232F000B34579 /* NativeModules */,
990CC4AB2A33104500AB6D8B /* SubWalletMobile.entitlements */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.mm */,
Expand All @@ -115,6 +119,23 @@
name = Frameworks;
sourceTree = "<group>";
};
355FCA132A7232F000B34579 /* NativeModules */ = {
isa = PBXGroup;
children = (
355FCA142A72333200B34579 /* RCTMinimizer */,
);
name = NativeModules;
sourceTree = "<group>";
};
355FCA142A72333200B34579 /* RCTMinimizer */ = {
isa = PBXGroup;
children = (
355FCA162A72335100B34579 /* RCTMinimizer.h */,
355FCA152A72335100B34579 /* RCTMinimizer.m */,
);
name = RCTMinimizer;
sourceTree = "<group>";
};
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -437,6 +458,7 @@
buildActionMask = 2147483647;
files = (
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
355FCA172A72335100B34579 /* RCTMinimizer.m in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
15 changes: 15 additions & 0 deletions ios/SubWalletMobile/NativeModules/RCTMinimizer/RCTMinimizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// RCTMinimizer.h
// SubWalletMobile
//
// Created by Do Minh Quang on 27/07/2023.
//

#ifndef RCTMinimizer_h
#define RCTMinimizer_h

#import <React/RCTBridgeModule.h>
@interface RCTMinimizer : NSObject <RCTBridgeModule>
@end

#endif /* RCTMinimizer_h */
30 changes: 30 additions & 0 deletions ios/SubWalletMobile/NativeModules/RCTMinimizer/RCTMinimizer.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#import <Foundation/Foundation.h>
#import "RCTMinimizer.h"

@import UIKit;
@import ObjectiveC.runtime;

@interface UISystemNavigationAction : NSObject
@property(nonatomic, readonly, nonnull) NSArray<NSNumber*>* destinations;
-(BOOL)sendResponseForDestination:(NSUInteger)destination;
@end


@implementation RCTMinimizer

RCT_EXPORT_METHOD(goBack)
{
Ivar sysNavIvar = class_getInstanceVariable(UIApplication.class, "_systemNavigationAction");
UIApplication* app = UIApplication.sharedApplication;
UISystemNavigationAction* action = object_getIvar(app, sysNavIvar);
if (!action) {
return;
}
NSUInteger destination = action.destinations.firstObject.unsignedIntegerValue;
[action sendResponseForDestination:destination];
return;
}

RCT_EXPORT_MODULE();

@end
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@fortawesome/free-regular-svg-icons": "^6.2.1",
"@fortawesome/free-solid-svg-icons": "^6.2.1",
"@fortawesome/react-native-fontawesome": "^0.3.0",
"@gorhom/portal": "^1.0.14",
"@polkadot/api": "^10.9.1",
"@polkadot/react-qr": "^3.5.1",
"@polkadot/reactnative-identicon": "^3.5.1",
Expand Down
18 changes: 14 additions & 4 deletions src/AppNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import ChangeMasterPassword from 'screens/MasterPassword/ChangeMasterPassword';
import { ImportNetwork } from 'screens/ImportNetwork';
import History from 'screens/Home/History';
import withPageWrapper from 'components/pageWrapper';
import { useSelector } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from 'stores/index';
import { AddProvider } from 'screens/AddProvider';
import TransactionScreen from 'screens/Transaction/TransactionScreen';
Expand All @@ -72,6 +72,7 @@ import urlParse from 'url-parse';
import queryString from 'querystring';
import { connectWalletConnect } from 'utils/walletConnect';
import { useToast } from 'react-native-toast-notifications';
import { updateIsDeepLinkConnect } from 'stores/base/Settings';

interface Props {
isAppReady: boolean;
Expand Down Expand Up @@ -143,6 +144,7 @@ const AppNavigator = ({ isAppReady }: Props) => {
const { hasConfirmations } = useSelector((state: RootState) => state.requestState);
const { accounts, hasMasterPassword } = useSelector((state: RootState) => state.accountState);
const toast = useToast();
const dispatch = useDispatch();

const needMigrate = useMemo(
() =>
Expand All @@ -168,8 +170,8 @@ const AppNavigator = ({ isAppReady }: Props) => {
let amount = true;
if (hasConfirmations && currentRoute && amount) {
if (currentRoute.name !== 'Confirmations' && amount) {
if (currentRoute.name !== 'CreateAccount' && amount) {
navigationRef.current?.navigate('Confirmations');
if (!['CreateAccount', 'CreatePassword'].includes(currentRoute.name) && amount) {
setTimeout(() => navigationRef.current?.navigate('Confirmations'), 1000);
}
}
}
Expand Down Expand Up @@ -205,12 +207,20 @@ const AppNavigator = ({ isAppReady }: Props) => {
const urlParsed = new urlParse(url);
if (getProtocol(url) === 'subwallet') {
if (urlParsed.hostname === 'wc') {
dispatch(updateIsDeepLinkConnect(true));
if (urlParsed.query.startsWith('?requestId')) {
return;
}
const decodedWcUrl = queryString.decode(urlParsed.query.slice(5));
const finalWcUrl = Object.keys(decodedWcUrl)[0];
connectWalletConnect(finalWcUrl, toast);
}
} else if (getProtocol(url) === 'https') {
if (urlParsed.pathname.split('/')[1] === 'wc') {
dispatch(updateIsDeepLinkConnect(true));
if (urlParsed.query.startsWith('?requestId')) {
return;
}
const decodedWcUrl = queryString.decode(urlParsed.query.slice(5));
const finalWcUrl = Object.keys(decodedWcUrl)[0];
connectWalletConnect(finalWcUrl, toast);
Expand All @@ -219,7 +229,7 @@ const AppNavigator = ({ isAppReady }: Props) => {
});

return () => Linking.removeAllListeners('url');
}, [toast]);
}, [dispatch, toast]);

return (
<NavigationContainer linking={linking} ref={navigationRef} theme={theme} onStateChange={onUpdateRoute}>
Expand Down
98 changes: 55 additions & 43 deletions src/AppNew.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { QrSignerContextProvider } from 'providers/QrSignerContext';
import { ScannerContextProvider } from 'providers/ScannerContext';
import { SigningContextProvider } from 'providers/SigningContext';
import React, { useEffect } from 'react';
import { AppState, Platform, StatusBar, StyleProp, View } from 'react-native';
import { AppState, Dimensions, Platform, StatusBar, StyleProp, View } from 'react-native';
import { ThemeContext } from 'providers/contexts';
import { THEME_PRESET } from 'styles/themes';
import { ToastProvider } from 'react-native-toast-notifications';
Expand All @@ -30,11 +30,9 @@ import { setBuildNumber } from './stores/AppVersion';
import { getBuildNumber } from 'react-native-device-info';
import { AppModalContextProvider } from './providers/AppModalContext';
import { CustomToast } from 'components/design-system-ui/toast';

const viewContainerStyle: StyleProp<any> = {
position: 'relative',
flex: 1,
};
import { PortalProvider } from '@gorhom/portal';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';

const layerScreenStyle: StyleProp<any> = {
top: 0,
Expand Down Expand Up @@ -156,44 +154,58 @@ export const AppNew = () => {
const isAppReady = isRequiredStoresReady && isCryptoReady && isI18nReady;

return (
<View style={viewContainerStyle}>
<View style={{ flex: 1 }}>
<ToastProvider
duration={TOAST_DURATION}
renderToast={toast => <CustomToast toast={toast} />}
placement="top"
normalColor={theme.colors.notification}
textStyle={{ textAlign: 'center', ...FontMedium }}
successColor={theme.colors.primary}
warningColor={theme.colors.notification_warning}
offsetTop={STATUS_BAR_HEIGHT + 40}
dangerColor={theme.colors.notification_danger}>
<ThemeContext.Provider value={theme}>
<SigningContextProvider>
<ExternalRequestContextProvider>
<QrSignerContextProvider>
<ScannerContextProvider>
<AppModalContextProvider>
<AppNavigator isAppReady={isAppReady} />
</AppModalContextProvider>
</ScannerContextProvider>
</QrSignerContextProvider>
</ExternalRequestContextProvider>
</SigningContextProvider>
</ThemeContext.Provider>
</ToastProvider>
</View>
{!isAppReady && (
<View style={layerScreenStyle}>
<LoadingScreen />
</View>
)}
{isLocked && (
<View style={layerScreenStyle}>
<LockScreen />
<SafeAreaProvider style={{ flex: 1 }}>
<>
<View style={{ flex: 1 }}>
<ToastProvider
duration={TOAST_DURATION}
renderToast={toast => <CustomToast toast={toast} />}
placement="top"
normalColor={theme.colors.notification}
textStyle={{ textAlign: 'center', ...FontMedium }}
successColor={theme.colors.primary}
warningColor={theme.colors.notification_warning}
offsetTop={STATUS_BAR_HEIGHT + 40}
dangerColor={theme.colors.notification_danger}>
<ThemeContext.Provider value={theme}>
<SigningContextProvider>
<ExternalRequestContextProvider>
<QrSignerContextProvider>
<ScannerContextProvider>
<AppModalContextProvider>
<GestureHandlerRootView
style={{
position: 'absolute',
top: 0,
left: 0,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
zIndex: 9999,
}}>
<PortalProvider>
<AppNavigator isAppReady={isAppReady} />
</PortalProvider>
</GestureHandlerRootView>
</AppModalContextProvider>
</ScannerContextProvider>
</QrSignerContextProvider>
</ExternalRequestContextProvider>
</SigningContextProvider>
</ThemeContext.Provider>
</ToastProvider>
</View>
)}
</View>
{!isAppReady && (
<View style={layerScreenStyle}>
<LoadingScreen />
</View>
)}
{isLocked && (
<View style={layerScreenStyle}>
<LockScreen />
</View>
)}
</>
</SafeAreaProvider>
);
};

Expand Down
Loading

0 comments on commit f259cd2

Please sign in to comment.