-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathApp.tsx
169 lines (156 loc) · 5.48 KB
/
App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import React, { useCallback, useEffect, useState } from 'react';
import { ActivityIndicator, Button, SafeAreaView, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import WalletConnectProvider, { useWalletConnect } from 'react-native-walletconnect';
import axios from 'axios';
const ETHERSCAN_API_KEY = 'REPLACE_WITH_YOUR_ETHERSCAN_API_KEY';
const TOKEN_CONTRACT_ADDRESS = '0xFab46E002BbF0b4509813474841E0716E6730136';
const WalletConnectExample = () => {
const [tokenContractAddress, setTokenContractAddress] = useState('');
const [ethBalance, setEthBalance] = useState(0);
const [tokenBalance, setTokenBalance] = useState(NaN);
const [isLoadingEthBalance, setIsLoadingEthBalance] = useState(false);
const [isLoadingTokenBalance, setIsLoadingTokenBalance] = useState(false);
const {
createSession,
killSession,
session,
} = useWalletConnect();
const fetchEthBalance = useCallback(async (account: string) => {
setIsLoadingEthBalance(true);
const response = await axios(
`https://api-kovan.etherscan.io/api?module=account&action=balance&address=${account}&tag=latest&apikey=${ETHERSCAN_API_KEY}`,
);
const balanceInWei = response.data.result;
const balanceInEther = Number(balanceInWei) / 1000000000000000000; // TODO: Use Web3 utils library for unit conversion
setEthBalance(balanceInEther);
setIsLoadingEthBalance(false);
}, [ETHERSCAN_API_KEY]);
const fetchTokenBalance = useCallback(async (tokenContractAddress: string, account: string) => {
setIsLoadingTokenBalance(true);
const response = await axios(
`https://api-kovan.etherscan.io/api?module=account&action=tokenbalance&contractaddress=${tokenContractAddress}&address=${account}&tag=latest&apikey=${ETHERSCAN_API_KEY}`,
);
const balanceInDecimals = response.data.result; // We'll assume the token has 18 decimals for the sake of this PoC's simplicity
const balance = Number(balanceInDecimals) / 1000000000000000000; // TODO: Use Web3 utils library for unit conversion
setTokenBalance(balance);
setIsLoadingTokenBalance(false);
}, [ETHERSCAN_API_KEY, tokenContractAddress]);
useEffect(() => {
if (session.length) {
const account = session[0].accounts[0]; // Using just the first account for the sake of this PoC's simplicity
fetchEthBalance(account);
}
}, [session]);
const hasWallet = !!session.length;
const account: string = session[0]?.accounts[0];
return (
<View style={styles.walletConnect}>
{!hasWallet && (
<Button title="Connect Wallet" onPress={createSession} />
)}
{hasWallet && (
<View style={styles.inputContainer}>
<View style={styles.tokenContractInputContainer}>
<TextInput
style={styles.tokenContractInput}
onChangeText={text => setTokenContractAddress(text)}
value={tokenContractAddress}
placeholder="ERC20 Token Contract Address"
onSubmitEditing={() => fetchTokenBalance(tokenContractAddress, account)}
autoCorrect={false}
autoCompleteType="off"
textContentType="none"
/>
<TouchableOpacity style={styles.tokenContractAutofill} onPress={() => setTokenContractAddress(TOKEN_CONTRACT_ADDRESS)}>
<Text style={styles.dot}>·</Text>
</TouchableOpacity>
</View>
<Text ellipsizeMode="middle" numberOfLines={1}>{`Account 1 (${account})`}</Text>
<Text style={styles.balanceText}>
{isLoadingEthBalance && <ActivityIndicator size="small" />}
{!Number.isNaN(ethBalance) ? `${ethBalance.toFixed(4)} ETH` : ''}
</Text>
<Text style={styles.balanceText}>
{isLoadingTokenBalance && <ActivityIndicator size="small" />}
{!Number.isNaN(tokenBalance) ? `${Number(tokenBalance).toFixed(2)} ERC20 TOKEN` : ''}
</Text>
</View>
)}
{hasWallet && (
<View style={styles.footer}>
<Button
title="Disconnect Wallet"
onPress={() => {
setEthBalance(0);
setTokenContractAddress('');
setTokenBalance(NaN);
setIsLoadingEthBalance(false);
setIsLoadingTokenBalance(false);
killSession();
}}
/>
</View>
)}
</View>
);
};
export default function App() {
return (
<WalletConnectProvider>
<SafeAreaView style={styles.container}>
<StatusBar style="auto" />
<WalletConnectExample />
</SafeAreaView>
</WalletConnectProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 25
},
walletConnect: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 25
},
inputContainer: {
width:'100%'
},
tokenContractInputContainer: {
flexDirection: 'row',
marginBottom: 25,
height: 35,
width: '100%',
},
tokenContractInput: {
flex: 1,
fontSize: 18,
borderBottomColor: 'lightgray',
borderBottomWidth: 1,
marginRight: 2.5
},
tokenContractAutofill: {
height: '100%',
aspectRatio: 1,
backgroundColor: 'lightgray',
alignItems: 'center',
justifyContent: 'center',
marginLeft: 2.5
},
dot: {
fontSize: 25,
fontWeight: 'bold',
paddingBottom: 2
},
balanceText: {
fontSize: 18,
fontWeight: 'bold'
},
footer: {
position: 'absolute',
bottom: 0
}
});