Skip to content

Commit eed99e7

Browse files
support Bitcoin: part 1: add connection QR code page
1 parent ee8a118 commit eed99e7

File tree

12 files changed

+422
-65
lines changed

12 files changed

+422
-65
lines changed

.eslintrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
module.exports = {
22
root: true,
33
extends: '@react-native',
4+
rules: {
5+
'react-native/no-inline-styles': 0,
6+
},
47
};

app/pages/Login/index.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ const LoginPage = ({route, navigation}: {navigation: any; route: any}) => {
114114
<TextInput
115115
style={[
116116
styles.textInput,
117-
// eslint-disable-next-line react-native/no-inline-styles
118117
{borderColor: editingPassword ? 'deepskyblue' : '#aaaaaa'},
119118
]}
120119
placeholder="Type your password"
@@ -145,7 +144,6 @@ const LoginPage = ({route, navigation}: {navigation: any; route: any}) => {
145144
<TextInput
146145
style={[
147146
styles.textInput,
148-
// eslint-disable-next-line react-native/no-inline-styles
149147
{borderColor: editingPassword ? 'deepskyblue' : '#aaaaaa'},
150148
]}
151149
placeholder="Type simple password"
@@ -176,7 +174,6 @@ const LoginPage = ({route, navigation}: {navigation: any; route: any}) => {
176174
<TextInput
177175
style={[
178176
styles.textInput,
179-
// eslint-disable-next-line react-native/no-inline-styles
180177
{borderColor: editingPassword ? 'deepskyblue' : '#aaaaaa'},
181178
]}
182179
placeholder="Type your PIN"
@@ -239,7 +236,6 @@ const LoginPage = ({route, navigation}: {navigation: any; route: any}) => {
239236
disabled={loginButtonIsDisable()}
240237
style={[
241238
styles.loginButton,
242-
// eslint-disable-next-line react-native/no-inline-styles
243239
{opacity: loginButtonIsDisable() ? 0.5 : 1},
244240
]}
245241
onPress={login}>

app/pages/Settings/AddressList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const AddressList = () => {
3838

3939
React.useEffect(() => {
4040
const _addressList = wallet
41-
.derivedAddressList(100)
41+
.derivedEVMAddressList(100)
4242
.map((address, index) => {
4343
return {id: index + 1, address: address};
4444
});

app/pages/Settings/BtcAddressList.tsx

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import React from 'react';
2+
import {
3+
SafeAreaView,
4+
Text,
5+
View,
6+
StyleSheet,
7+
Linking,
8+
TouchableOpacity,
9+
ActivityIndicator,
10+
FlatList,
11+
} from 'react-native';
12+
13+
import * as wallet from '../../wallet';
14+
// @ts-ignore
15+
import Icon from 'react-native-vector-icons/Ionicons';
16+
17+
const jumpToEthscan = (address: string) => {
18+
Linking.openURL('https://etherscan.io/address/' + address);
19+
};
20+
21+
type ItemProps = {
22+
address: string;
23+
id: number;
24+
};
25+
26+
const Item = ({address, index}: {address: string; index: number}) => (
27+
<TouchableOpacity style={styles.cell} onPress={() => jumpToEthscan(address)}>
28+
<Text style={styles.index}>{index}.</Text>
29+
<View style={styles.line}>
30+
<Text style={styles.address}>{address}</Text>
31+
<Icon name="chevron-forward" size={24} color="#AAAAAA" />
32+
</View>
33+
</TouchableOpacity>
34+
);
35+
36+
const AddressList = () => {
37+
const [addressList, setAddressList] = React.useState<ItemProps[]>([]);
38+
39+
React.useEffect(() => {
40+
const _addressList = wallet
41+
.derivedBTCAddressList(1, true)
42+
.map((address, index) => {
43+
return {id: index + 1, address: address};
44+
});
45+
46+
setAddressList(_addressList);
47+
}, []);
48+
49+
if (addressList.length === 0) {
50+
return (
51+
<SafeAreaView style={styles.indicatorContainer}>
52+
<ActivityIndicator size="large" />
53+
</SafeAreaView>
54+
);
55+
}
56+
57+
return (
58+
<SafeAreaView style={styles.container}>
59+
<FlatList
60+
data={addressList}
61+
style={styles.container}
62+
contentContainerStyle={styles.contentContainer}
63+
renderItem={({item}) => <Item address={item.address} index={item.id} />}
64+
/>
65+
</SafeAreaView>
66+
);
67+
};
68+
69+
const styles = StyleSheet.create({
70+
container: {
71+
height: '100%',
72+
width: '100%',
73+
},
74+
indicatorContainer: {
75+
flex: 1,
76+
flexDirection: 'column',
77+
justifyContent: 'center',
78+
alignItems: 'center',
79+
},
80+
contentContainer: {
81+
width: '100%',
82+
flexDirection: 'column',
83+
alignItems: 'center',
84+
padding: 10,
85+
},
86+
cell: {
87+
width: '100%',
88+
flexDirection: 'row',
89+
justifyContent: 'space-between',
90+
alignItems: 'center',
91+
paddingLeft: 5,
92+
height: 32,
93+
marginTop: 10,
94+
},
95+
line: {
96+
flex: 1,
97+
marginLeft: 4,
98+
borderBottomWidth: 1,
99+
height: '100%',
100+
borderBottomColor: 'lightgray',
101+
flexDirection: 'row',
102+
// justifyContent: 'flex-end',
103+
justifyContent: 'space-between',
104+
alignItems: 'center',
105+
},
106+
label: {
107+
fontSize: 17,
108+
},
109+
index: {
110+
fontSize: 17,
111+
width: 24,
112+
},
113+
address: {
114+
fontSize: 14,
115+
marginTop: 2,
116+
},
117+
});
118+
export default AddressList;

app/pages/Settings/ConnectionQR.tsx

Lines changed: 89 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,110 @@
11
import React from 'react';
22
import {
33
SafeAreaView,
4-
Text,
4+
// Text,
55
View,
66
StyleSheet,
77
useWindowDimensions,
88
ActivityIndicator,
9+
Linking,
910
} from 'react-native';
1011
import QRCode from 'react-native-qrcode-svg';
12+
import {Tab, Text, TabView, Button} from '@rneui/themed';
1113
import * as wallet from '../../wallet';
1214

1315
const ConnectionQRCodePage = () => {
14-
const [ur, setUr] = React.useState<string | undefined>(undefined);
16+
const [evmUR, setEvmUR] = React.useState<string | undefined>(undefined);
17+
const [btcUR, setBtcUR] = React.useState<string | undefined>(undefined);
18+
const [tabIndex, setTabIndex] = React.useState(0);
1519
const {width} = useWindowDimensions();
1620
React.useEffect(() => {
17-
setUr(wallet.getWallet()!.getConnectionUR());
18-
}, [setUr]);
21+
setEvmUR(wallet.getWallet()!.EVMWallet.getConnectionUR());
22+
setBtcUR(wallet.getWallet()!.BTCWallet.getConnectionUR());
23+
}, [setBtcUR, setEvmUR]);
24+
25+
const getMetaMask = () => {
26+
Linking.openURL('https://metamask.io/');
27+
};
28+
29+
const getBlueWallet = () => {
30+
Linking.openURL('https://bluewallet.io/');
31+
};
1932

2033
return (
2134
<SafeAreaView style={styles.container}>
22-
{ur === undefined ? (
35+
{evmUR === undefined || btcUR === undefined ? (
2336
<ActivityIndicator />
2437
) : (
25-
<View style={styles.textContainer}>
26-
<QRCode size={width - 40} value={ur} />
27-
<Text style={styles.normalText}>
28-
Use your MetaMask Wallet to scan this QRCode to connect.{'\n'} (Add
29-
account or hardware wallet -- Connect a hardware wallet -- QR-Based
30-
)
31-
</Text>
38+
<View style={styles.container}>
39+
<Tab
40+
value={tabIndex}
41+
onChange={e => setTabIndex(e)}
42+
style={{width: '100%', height: 60}}
43+
indicatorStyle={{
44+
backgroundColor: 'white',
45+
height: 3,
46+
}}
47+
variant="primary">
48+
<Tab.Item
49+
title="EVM"
50+
titleStyle={{fontSize: 12}}
51+
icon={{
52+
name: 'ethereum',
53+
type: 'material-community',
54+
color: 'white',
55+
}}
56+
/>
57+
<Tab.Item
58+
title="Bitcoin"
59+
titleStyle={{fontSize: 12}}
60+
icon={{
61+
name: 'bitcoin',
62+
type: 'material-community',
63+
color: 'white',
64+
}}
65+
/>
66+
</Tab>
67+
<TabView
68+
containerStyle={{
69+
flex: 1,
70+
width: '100%',
71+
height: '100%',
72+
}}
73+
value={tabIndex}
74+
onChange={setTabIndex}
75+
animationType="spring">
76+
<TabView.Item style={{width: '100%'}}>
77+
<View style={styles.textContainer}>
78+
<QRCode size={width - 40} value={evmUR} />
79+
<Text style={styles.normalText}>
80+
Use your MetaMask Wallet to scan this QRCode to connect.{'\n'}{' '}
81+
(Add account or hardware wallet -- Connect a hardware wallet
82+
-- QR-Based )
83+
</Text>
84+
<Button
85+
title="get MetaMask"
86+
type="clear"
87+
onPress={getMetaMask}
88+
style={{marginTop: 25}}
89+
/>
90+
</View>
91+
</TabView.Item>
92+
<TabView.Item style={{width: '100%'}}>
93+
<View style={styles.textContainer}>
94+
<QRCode size={width - 40} value={btcUR} />
95+
<Text style={styles.normalText}>
96+
Use your hot wallet to scan this QRCode to connect.{'\n'} We
97+
recommend Blue Wallet!
98+
</Text>
99+
<Button
100+
title="get BlueWallet"
101+
type="clear"
102+
onPress={getBlueWallet}
103+
style={{marginTop: 25}}
104+
/>
105+
</View>
106+
</TabView.Item>
107+
</TabView>
32108
</View>
33109
)}
34110
</SafeAreaView>
@@ -43,6 +119,7 @@ const styles = StyleSheet.create({
43119
flexDirection: 'column',
44120
alignItems: 'center',
45121
justifyContent: 'center',
122+
overflow: 'hidden',
46123
},
47124
normalText: {
48125
marginTop: 20,

app/pages/Setup/SecuritySetting.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,11 +391,7 @@ const SecuritySettingPage = ({
391391
<TouchableOpacity
392392
activeOpacity={0.6}
393393
disabled={buttonIsDisable()}
394-
style={[
395-
styles.button,
396-
// eslint-disable-next-line react-native/no-inline-styles
397-
{opacity: buttonIsDisable() ? 0.5 : 1},
398-
]}
394+
style={[styles.button, {opacity: buttonIsDisable() ? 0.5 : 1}]}
399395
onPress={complete}>
400396
<Text style={styles.buttonText}>
401397
{setupComplete !== undefined ? 'Complete' : 'Save'}

app/pages/Setup/SetPassword.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ const SetPasswordPage = ({
7878
<TextInput
7979
style={[
8080
styles.textInput,
81-
// eslint-disable-next-line react-native/no-inline-styles
8281
{borderColor: editingPassword ? 'deepskyblue' : '#aaaaaa'},
8382
]}
8483
placeholder="Password: at least 8 characters"

app/pages/Setup/index.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ const SetupPage = ({navigation}: {navigation: any}) => {
200200
<TextInput
201201
style={[
202202
styles.textInput,
203-
// eslint-disable-next-line react-native/no-inline-styles
204203
{borderColor: editingText ? 'deepskyblue' : '#aaaaaa'},
205204
]}
206205
placeholder="Type random text, at least 16 characters"
@@ -227,11 +226,7 @@ const SetupPage = ({navigation}: {navigation: any}) => {
227226
<TouchableOpacity
228227
activeOpacity={0.6}
229228
disabled={hashButtonDisable()}
230-
style={[
231-
styles.button,
232-
// eslint-disable-next-line react-native/no-inline-styles
233-
{opacity: hashButtonDisable() ? 0.5 : 1},
234-
]}
229+
style={[styles.button, {opacity: hashButtonDisable() ? 0.5 : 1}]}
235230
onPress={generateMnemonicByText}>
236231
<Text style={styles.buttonText}>Hash Text</Text>
237232
</TouchableOpacity>
@@ -242,12 +237,7 @@ const SetupPage = ({navigation}: {navigation: any}) => {
242237
{/* <Text>{mnemonic}</Text> */}
243238
<MnemonicView mnemonic={mnemonic.split(' ')} />
244239

245-
<Text
246-
style={[
247-
styles.normalText,
248-
// eslint-disable-next-line react-native/no-inline-styles
249-
{paddingLeft: 20},
250-
]}>
240+
<Text style={[styles.normalText, {paddingLeft: 20}]}>
251241
Now, you can set password.
252242
</Text>
253243
<TouchableOpacity

app/pages/Sign/index.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,11 @@ const SignPage = ({route}: {route: any}) => {
4545
);
4646
React.useEffect(() => {
4747
try {
48-
const req = wallet.parseRequest(ur);
49-
if (!wallet.checkAddressCanBeDerived(req.address, req.derivationPath)) {
48+
// TODO btc sign page, check ur type
49+
const req = wallet.parseEVMRequest(ur);
50+
if (
51+
!wallet.checkEVMAddressCanBeDerived(req.address, req.derivationPath)
52+
) {
5053
setWrongUr(true);
5154
// console.log('address can not be derived');
5255
Toast.show({
@@ -92,7 +95,7 @@ const SignPage = ({route}: {route: any}) => {
9295
}
9396

9497
const sign = () => {
95-
const signedUr = wallet.signRequest(request);
98+
const signedUr = wallet.signEVMRequest(request);
9699
setSignedUrText(signedUr);
97100
setTimeout(() => {
98101
if (scrollViewRef.current) {

0 commit comments

Comments
 (0)