diff --git a/android/app/build.gradle b/android/app/build.gradle
index 6f1a63b67a26..f8cdab0b8f66 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -274,7 +274,8 @@ dependencies {
implementation "com.facebook.react:react-native:+" // From node_modules
implementation project(':react-native-branch')
- implementation "io.branch.sdk.android:library:3.0.4"
+ implementation "io.branch.sdk.android:library:4.1.2"
+
implementation project(':react-native-camera')
implementation project(':react-native-share')
diff --git a/app/components/Nav/Main/index.js b/app/components/Nav/Main/index.js
index be84cf050584..45ebca5b6496 100644
--- a/app/components/Nav/Main/index.js
+++ b/app/components/Nav/Main/index.js
@@ -87,6 +87,7 @@ import contractMap from 'eth-contract-metadata';
import { BN } from 'gaba';
import { BNToHex } from 'gaba/util';
import MessageSign from '../../UI/MessageSign';
+import WalletConnectReturnToBrowserModal from '../../UI/WalletConnectReturnToBrowserModal';
const styles = StyleSheet.create({
flex: {
@@ -384,6 +385,7 @@ class Main extends PureComponent {
signType: '',
walletConnectRequest: false,
walletConnectRequestInfo: {},
+ walletConnectReturnModalVisible: false,
paymentChannelRequest: false,
paymentChannelRequestLoading: false,
paymentChannelRequestCompleted: false,
@@ -498,6 +500,9 @@ class Main extends PureComponent {
WalletConnect.hub.on('walletconnectSessionRequest', peerInfo => {
this.setState({ walletConnectRequest: true, walletConnectRequestInfo: peerInfo });
});
+ WalletConnect.hub.on('walletconnect:return', () => {
+ this.setState({ walletConnectReturnModalVisible: true });
+ });
WalletConnect.init();
};
@@ -739,6 +744,7 @@ class Main extends PureComponent {
// If the app is now in background, we need to start
// the background timer, which is less intense
if (this.backgroundMode) {
+ this.setState({ walletConnectReturnModalVisible: false });
BackgroundTimer.runBackgroundTimer(async () => {
await Engine.refreshTransactionHistory();
}, AppConstants.TX_CHECK_BACKGROUND_FREQUENCY);
@@ -902,6 +908,10 @@ class Main extends PureComponent {
);
};
+ renderWalletConnectReturnModal = () => (
+
+ );
+
renderPaymentChannelRequestApproval = () => {
const {
paymentChannelRequest,
@@ -952,6 +962,7 @@ class Main extends PureComponent {
{this.renderSigningModal()}
{this.renderWalletConnectSessionRequestModal()}
{this.renderPaymentChannelRequestApproval()}
+ {this.renderWalletConnectReturnModal()}
);
}
diff --git a/app/components/UI/BlockingActionModal/__snapshots__/index.test.js.snap b/app/components/UI/BlockingActionModal/__snapshots__/index.test.js.snap
new file mode 100644
index 000000000000..877a1a1b324a
--- /dev/null
+++ b/app/components/UI/BlockingActionModal/__snapshots__/index.test.js.snap
@@ -0,0 +1,81 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`BlockingActionModal should render correctly 1`] = `
+
+
+
+
+ Please wait
+
+
+
+
+
+`;
diff --git a/app/components/UI/BlockingActionModal/index.js b/app/components/UI/BlockingActionModal/index.js
new file mode 100644
index 000000000000..eafdc7ae3dca
--- /dev/null
+++ b/app/components/UI/BlockingActionModal/index.js
@@ -0,0 +1,56 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { ActivityIndicator, StyleSheet, View } from 'react-native';
+import Modal from 'react-native-modal';
+import { colors, baseStyles } from '../../../styles/common';
+
+const styles = StyleSheet.create({
+ modal: {
+ margin: 0,
+ width: '100%'
+ },
+ modalView: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ alignSelf: 'center',
+ backgroundColor: colors.white,
+ width: '90%',
+ borderRadius: 6,
+ minHeight: 200,
+ padding: 15
+ },
+ loader: {
+ marginTop: 30
+ }
+});
+
+/**
+ * View that renders an action modal
+ */
+export default function BlockingActionModal({ children, modalVisible, isLoadingAction }) {
+ return (
+
+
+
+ {children}
+ {isLoadingAction && }
+
+
+
+ );
+}
+
+BlockingActionModal.propTypes = {
+ /**
+ * Whether modal is shown
+ */
+ modalVisible: PropTypes.bool,
+ /**
+ * Whether a spinner is shown
+ */
+ isLoadingAction: PropTypes.bool,
+ /**
+ * Content to display above the action buttons
+ */
+ children: PropTypes.node
+};
diff --git a/app/components/UI/BlockingActionModal/index.test.js b/app/components/UI/BlockingActionModal/index.test.js
new file mode 100644
index 000000000000..65049b241754
--- /dev/null
+++ b/app/components/UI/BlockingActionModal/index.test.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import { Text } from 'react-native';
+import { shallow } from 'enzyme';
+import BlockingActionModal from './';
+
+describe('BlockingActionModal', () => {
+ it('should render correctly', () => {
+ const wrapper = shallow(
+
+ Please wait
+
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/app/components/UI/WalletConnectReturnToBrowserModal/__snapshots__/index.test.js.snap b/app/components/UI/WalletConnectReturnToBrowserModal/__snapshots__/index.test.js.snap
new file mode 100644
index 000000000000..49238492ef09
--- /dev/null
+++ b/app/components/UI/WalletConnectReturnToBrowserModal/__snapshots__/index.test.js.snap
@@ -0,0 +1,51 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`WalletConnectReturnToBrowserModal should render correctly 1`] = `
+
+
+ You're all set!
+
+
+ You can now return to your browser
+
+
+
+`;
diff --git a/app/components/UI/WalletConnectReturnToBrowserModal/index.js b/app/components/UI/WalletConnectReturnToBrowserModal/index.js
new file mode 100644
index 000000000000..5ec71eec0fc7
--- /dev/null
+++ b/app/components/UI/WalletConnectReturnToBrowserModal/index.js
@@ -0,0 +1,54 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { StyleSheet, Text } from 'react-native';
+import Icon from 'react-native-vector-icons/Ionicons';
+import { fontStyles, colors } from '../../../styles/common';
+import { strings } from '../../../../locales/i18n';
+import BlockingActionModal from '../BlockingActionModal';
+
+const styles = StyleSheet.create({
+ blockingModalText: {
+ alignSelf: 'center',
+ borderRadius: 10,
+ fontSize: 16,
+ textAlign: 'center',
+ color: colors.fontSecondary,
+ ...fontStyles.normal
+ },
+ blockingModalTitle: {
+ color: colors.fontPrimary,
+ fontSize: 22,
+ marginBottom: 15,
+ textAlign: 'center',
+ ...fontStyles.bold
+ },
+ returnIcon: {
+ marginTop: 15,
+ textAlign: 'center',
+ color: colors.fontSecondary,
+ fontSize: 60,
+ lineHeight: 60
+ }
+});
+
+/**
+ * View that renders an action modal
+ */
+export default function WalletConnectReturnToBrowserModal({ modalVisible }) {
+ return (
+
+
+ {strings('walletconnect_return_modal.title')}
+ {strings('walletconnect_return_modal.text')}
+
+
+
+ );
+}
+
+WalletConnectReturnToBrowserModal.propTypes = {
+ /**
+ * Whether modal is shown
+ */
+ modalVisible: PropTypes.bool
+};
diff --git a/app/components/UI/WalletConnectReturnToBrowserModal/index.test.js b/app/components/UI/WalletConnectReturnToBrowserModal/index.test.js
new file mode 100644
index 000000000000..0e6f5eb2f0bb
--- /dev/null
+++ b/app/components/UI/WalletConnectReturnToBrowserModal/index.test.js
@@ -0,0 +1,10 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import WalletConnectReturnToBrowserModal from './';
+
+describe('WalletConnectReturnToBrowserModal', () => {
+ it('should render correctly', () => {
+ const wrapper = shallow();
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/app/core/DeeplinkManager.js b/app/core/DeeplinkManager.js
index 54b5b8c5f8fc..b6a05bafbe27 100644
--- a/app/core/DeeplinkManager.js
+++ b/app/core/DeeplinkManager.js
@@ -110,12 +110,7 @@ class DeeplinkManager {
const redirect = params && params.redirect;
// eslint-disable-next-line no-case-declarations
const autosign = params && params.autosign;
-
- if (urlObj.hostname === 'sign' || urlObj.hostname === 'send') {
- WalletConnect.setRedirectUri(redirect);
- } else {
- WalletConnect.newSession(url, redirect, autosign);
- }
+ WalletConnect.newSession(url, redirect, autosign);
break;
case 'ethereum':
this.handleEthereumUrl(url);
diff --git a/app/core/WalletConnect.js b/app/core/WalletConnect.js
index 0a216fc7df90..36b0c4d200a6 100644
--- a/app/core/WalletConnect.js
+++ b/app/core/WalletConnect.js
@@ -1,6 +1,5 @@
import RNWalletConnect from '@walletconnect/react-native';
import Engine from './Engine';
-import { Linking } from 'react-native';
import Logger from '../util/Logger';
// eslint-disable-next-line import/no-nodejs-modules
import { EventEmitter } from 'events';
@@ -8,7 +7,6 @@ import AsyncStorage from '@react-native-community/async-storage';
const hub = new EventEmitter();
let connectors = [];
-let pendingRedirect = null;
const CLIENT_OPTIONS = {
clientMeta: {
@@ -37,7 +35,7 @@ class WalletConnect {
constructor(options) {
if (options.redirect) {
- pendingRedirect = options.redirect;
+ this.redirectUrl = options.redirect;
}
if (options.autosign) {
@@ -207,6 +205,7 @@ class WalletConnect {
});
}
}
+ this.redirectIfNeeded();
}
});
@@ -290,11 +289,10 @@ class WalletConnect {
});
redirectIfNeeded = () => {
- if (pendingRedirect) {
+ if (this.redirectUrl) {
setTimeout(() => {
- Linking.openURL(pendingRedirect);
- pendingRedirect = null;
- }, 500);
+ hub.emit('walletconnect:return');
+ }, 1500);
}
};
}
@@ -353,9 +351,6 @@ const instance = {
shutdown() {
Engine.context.TransactionController.hub.removeAllListeners();
Engine.context.PreferencesController.unsubscribe();
- },
- setRedirectUri: uri => {
- pendingRedirect = uri;
}
};
diff --git a/locales/en.json b/locales/en.json
index f097eff8c3f6..508e2e269fd4 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -986,5 +986,9 @@
"amount_error_message": "The amount must be a number",
"address_error_message": "The address is invalid",
"balance_error_message": "Insufficient balance"
+ },
+ "walletconnect_return_modal": {
+ "title": "You're all set!",
+ "text": "You can now return to your browser"
}
}
diff --git a/locales/es.json b/locales/es.json
index 5a5a34d85189..8b35ecfddd64 100644
--- a/locales/es.json
+++ b/locales/es.json
@@ -966,5 +966,9 @@
"amount_error_message": "El monto debe ser un número",
"address_error_message": "La dirección no es válida",
"balance_error_message": "Balance insuficiente"
+ },
+ "walletconnect_return_modal": {
+ "title": "Listo!",
+ "text": "Ahora puedes volver a tu navegador"
}
}