Skip to content

Commit

Permalink
walletconnect deeplink support v2 (#1181)
Browse files Browse the repository at this point in the history
* walletconnect deeplink support

* fix

* Update WalletConnect.js
  • Loading branch information
Bruno Barbieri authored Nov 8, 2019
1 parent 749fee6 commit bc129b5
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 17 deletions.
3 changes: 2 additions & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
11 changes: 11 additions & 0 deletions app/components/Nav/Main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -384,6 +385,7 @@ class Main extends PureComponent {
signType: '',
walletConnectRequest: false,
walletConnectRequestInfo: {},
walletConnectReturnModalVisible: false,
paymentChannelRequest: false,
paymentChannelRequestLoading: false,
paymentChannelRequestCompleted: false,
Expand Down Expand Up @@ -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();
};

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -902,6 +908,10 @@ class Main extends PureComponent {
);
};

renderWalletConnectReturnModal = () => (
<WalletConnectReturnToBrowserModal modalVisible={this.state.walletConnectReturnModalVisible} />
);

renderPaymentChannelRequestApproval = () => {
const {
paymentChannelRequest,
Expand Down Expand Up @@ -952,6 +962,7 @@ class Main extends PureComponent {
{this.renderSigningModal()}
{this.renderWalletConnectSessionRequestModal()}
{this.renderPaymentChannelRequestApproval()}
{this.renderWalletConnectReturnModal()}
</React.Fragment>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`BlockingActionModal should render correctly 1`] = `
<ReactNativeModal
animationIn="slideInUp"
animationInTiming={300}
animationOut="slideOutDown"
animationOutTiming={300}
avoidKeyboard={false}
backdropColor="black"
backdropOpacity={0.7}
backdropTransitionInTiming={300}
backdropTransitionOutTiming={300}
deviceHeight={null}
deviceWidth={null}
hasBackdrop={true}
hideModalContentWhileAnimating={false}
isVisible={true}
onBackButtonPress={[Function]}
onBackdropPress={[Function]}
onModalHide={[Function]}
onModalShow={[Function]}
onModalWillHide={[Function]}
onModalWillShow={[Function]}
scrollOffset={0}
scrollOffsetMax={0}
scrollTo={null}
style={
Object {
"margin": 0,
"width": "100%",
}
}
supportedOrientations={
Array [
"portrait",
"landscape",
]
}
swipeThreshold={100}
useNativeDriver={false}
>
<View
style={
Object {
"alignItems": "center",
"alignSelf": "center",
"backgroundColor": "#FFFFFF",
"borderRadius": 6,
"justifyContent": "center",
"minHeight": 200,
"padding": 15,
"width": "90%",
}
}
>
<View
style={
Object {
"flex": 1,
}
}
>
<Text>
Please wait
</Text>
<ActivityIndicator
animating={true}
color="#999999"
hidesWhenStopped={true}
size="small"
style={
Object {
"marginTop": 30,
}
}
/>
</View>
</View>
</ReactNativeModal>
`;
56 changes: 56 additions & 0 deletions app/components/UI/BlockingActionModal/index.js
Original file line number Diff line number Diff line change
@@ -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 (
<Modal isVisible={modalVisible} style={styles.modal}>
<View style={styles.modalView}>
<View style={baseStyles.flexGrow}>
{children}
{isLoadingAction && <ActivityIndicator style={styles.loader} size={'small'} />}
</View>
</View>
</Modal>
);
}

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
};
15 changes: 15 additions & 0 deletions app/components/UI/BlockingActionModal/index.test.js
Original file line number Diff line number Diff line change
@@ -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(
<BlockingActionModal isLoadingAction modalVisible>
<Text>Please wait</Text>
</BlockingActionModal>
);
expect(wrapper).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`WalletConnectReturnToBrowserModal should render correctly 1`] = `
<BlockingActionModal
modalVisible={true}
>
<Text
style={
Object {
"color": "#000000",
"fontFamily": "Roboto",
"fontSize": 22,
"fontWeight": "600",
"marginBottom": 15,
"textAlign": "center",
}
}
>
You're all set!
</Text>
<Text
style={
Object {
"alignSelf": "center",
"borderRadius": 10,
"color": "#777777",
"fontFamily": "Roboto",
"fontSize": 16,
"fontWeight": "400",
"textAlign": "center",
}
}
>
You can now return to your browser
</Text>
<Icon
allowFontScaling={false}
name="md-exit"
size={12}
style={
Object {
"color": "#777777",
"fontSize": 60,
"lineHeight": 60,
"marginTop": 15,
"textAlign": "center",
}
}
/>
</BlockingActionModal>
`;
54 changes: 54 additions & 0 deletions app/components/UI/WalletConnectReturnToBrowserModal/index.js
Original file line number Diff line number Diff line change
@@ -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 (
<BlockingActionModal modalVisible={modalVisible}>
<React.Fragment>
<Text style={styles.blockingModalTitle}>{strings('walletconnect_return_modal.title')}</Text>
<Text style={styles.blockingModalText}>{strings('walletconnect_return_modal.text')}</Text>
<Icon name="md-exit" style={styles.returnIcon} />
</React.Fragment>
</BlockingActionModal>
);
}

WalletConnectReturnToBrowserModal.propTypes = {
/**
* Whether modal is shown
*/
modalVisible: PropTypes.bool
};
10 changes: 10 additions & 0 deletions app/components/UI/WalletConnectReturnToBrowserModal/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import { shallow } from 'enzyme';
import WalletConnectReturnToBrowserModal from './';

describe('WalletConnectReturnToBrowserModal', () => {
it('should render correctly', () => {
const wrapper = shallow(<WalletConnectReturnToBrowserModal modalVisible />);
expect(wrapper).toMatchSnapshot();
});
});
7 changes: 1 addition & 6 deletions app/core/DeeplinkManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit bc129b5

Please sign in to comment.