Connecting React Native App to Crypto Wallet.
Tags: reactnative, blockchain, web3, trustwallet
Published: 2023-06-17 13:00:56

Hello everyone, 👋, in this blog, I will show you how you can connect your React Native application to a wallet on your phone, you might be building an application where you need a user to pay with cryptocurrency in their wallet or you want a user to authenticate using their wallet address, well , you have come to the right place.

## Prerequisites
1. React Native knowledge
2. Javascript

Let's begin, we start by creating a new react native application, I will be using Expo but feel free to switch to using the CLI, go to your terminal and create a React Native application

```
$ npx create-expo-app MyApp
```
Follow the prompt if there is any then initialize a new application.
Then we open the installation in VSCODE.
```
$cd MyApp
$code .
```
When you Open the Application, you'll be greeted by page showing all elements.

Let us change our ``App.js`` file and we add a few elements and styling, paste the following lines of code
```
import { StatusBar } from 'expo-status-bar';
import './global';
import { StyleSheet, ImageBackground,SafeAreaView, Platform,View } from 'react-native';
import React, { useState } from 'react';
import MainPage from './screens/MainPage';
import WalletConnectProvider from "@walletconnect/react-native-dapp";
import AsyncStorage from "@react-native-async-storage/async-storage";
const SCHEME_FROM_APP_JSON = "walletconnect-example";

export default function App() {
	let screen = <MainPage/>;
	return (
		<>
			<StatusBar style="dark" />
			<ImageBackground style={{flex:1}} imageStyle={{opacity: .5}} resizeMode='cover' source={require('./assets/background.jpg')}>
				<SafeAreaView style={styles.container}>
					<WalletConnectProvider
						redirectUrl={
							Platform.OS === "web"
							? window.location.origin
							: `${SCHEME_FROM_APP_JSON}://`
						}
						storageOptions={{
							asyncStorage: AsyncStorage,
						}}
						>
						<View style={styles.container}>
							{/* <StatusBar style="auto" /> */}
							{screen}
							{/* <WalletConnectExperience functionStateHandler={functionStateHandler} /> */}
						</View>
					</WalletConnectProvider>
				</SafeAreaView>
			</ImageBackground>
		</>
	);
}

const styles = StyleSheet.create({
	container: {
		flex: 1,
		alignItems: 'center',
		justifyContent: 'center',
	},
	backgroundImage:{
		// opacity: .15,
		flex:1,
		// backgroundColor:'rgba(0,0,0,.5)'
	}
});

```
With this, I have wrapped the main page with the ``WalletConnectProvider``. We will see this later in action
Now let's create a ``components`` folder and then we create a component called ``Button.component.jsx``. Inside the file, paste the following code.
```
import React from 'react';
import { StyleSheet, Text, View, Pressable } from 'react-native';
function Button({children,onPress, widthSet}) {
    return (
        <View style={[styles.buttonOuterContainer,{width: widthSet,}]}>
            <Pressable
                style={({ pressed }) =>
                    pressed
                        ? [styles.pressed, styles.button_Inner_container]
                        : styles.button_Inner_container
                }
                android_ripple={{ color: '#6CA9F9' }}
                onPress={onPress}
            >
                <Text style={styles.buttonText}>{children}</Text>
            </Pressable>
        </View>
    );
}
const styles = StyleSheet.create({
    button_Inner_container: {
        backgroundColor: '#4E97F5',
        
        paddingVertical: 16,
        paddingHorizontal: 16,
        elevation: 4,
    },
    buttonOuterContainer: {
        
        margin: 4,
        borderRadius: 1,
        overflow: "hidden",
    },
    buttonText: {
        color: "#fff",
        textAlign: "center",
    },
    pressed: {
        opacity: 0.75,
    },
});
export default Button;
```
We have just added a button and styled it. Nothing fancy at all.
...
Now, let's create a folder called ``screens`` and the we add a page called ``MainPage.jsx``, let us install a library
```
 $ npm install react-native-dropdown-picker
```
Inside the mainpage, paste the following lines of code

```
import React,{useEffect} from 'react';
import { StyleSheet,TouchableOpacity, Text,FlatList, View, Dimensions, TextInput, ScrollView, Alert } from 'react-native';
import {Dropdown} from 'react-native-element-dropdown';
import { AntDesign } from '@expo/vector-icons';
import ButtonComponent from '../components/Button.component.jsx'
function MainPage() {
    const { height } = Dimensions.get('window');
    const connector = useWalletConnect();
    const [isFocus, setIsFocus] = React.useState(false);
    const [value, setValue] = React.useState({wallet:0, amount:0, receiver: ''});
    const [transactionHistory,setTransactionHistory] = React.useState([]);
    const [ownerAddress,setOwnerAddress] = React.useState('');
 
    
    
    
    return (
        <View style={{flex:1,marginTop:height*.09,position:'relative'}}>
            <View  style={{flexDirection:'row',alignItems:'center',justifyContent: 'space-between',marginHorizontal:7 }}>
                <View style={{flexDirection:'row', alignItems:'center'}}>
                    <Text style={styles.boldText}>Total Sent:</Text>
                    <Text style={styles.boldText}>0 BTC</Text>
                </View>
                <View style={{flexDirection:'row', alignItems:'center'}}>
                    
                        <>
                          <Text style={styles.boldText}>Wallet Address</Text>
                             <ButtonComponent widthSet={'20%'} onPress={()=>{}} >Log out</ButtonComponent>
                       </>
                        
                </View>
            </View>
            <Text style={[styles.boldText,{marginTop:height*.04, textAlign:'center'}]}> Send only 5 BTC per transaction</Text>

            <Dropdown
                style={[styles.dropdown, isFocus && { borderColor: '#000' }]}
                placeholderStyle={styles.placeholderStyle}
                selectedTextStyle={styles.selectedTextStyle}
                inputSearchStyle={styles.inputSearchStyle}
                iconStyle={styles.iconStyle}
                data={[
                    { label: "Blockchain", value: 1},
                    {label:"Trust Wallet",value: 2},
                    {label:"Binance",value: 3},
                ]}
                search
                maxHeight={300}
                labelField="label"
                valueField="value"
                placeholder={!isFocus ? 'Select Account' : '...'}
                searchPlaceholder="Search..."
                value={value.wallet}
                onFocus={() => setIsFocus(true)}
                onBlur={() => setIsFocus(false)}
                onChange={item => {
                    setValue({wallet: item.value});
                    setIsFocus(false);
                }}
                renderLeftIcon={() => (
                    <AntDesign style={styles.icon}
                        color={isFocus ? '#fff' : 'black'}
                        name="Safety"
                        size={20}
                    />
                )}
            />
            <View style={{marginTop:height*.04,alignItems:'center',flexDirection:'row'}}>
                <Text style={styles.boldText} >Receiver's Wallet:</Text>
                <TextInput keyboardType='twitter' 
                    style={[styles.textInput,{width:'70%'}]} 
                    placeholder="0.00000000" 
                    
                />
            </View>
            <View style={{marginTop:height*.04,justifyContent:'space-evenly',alignItems:'center',flexDirection:'row'}}>
                <Text style={styles.boldText}>BTC Amount</Text>
                <TextInput keyboardType='number-pad' 
                    style={styles.textInput} 
                    placeholder="0.00000000" 
                    
                />
                <Button widthSet={'20%'} label={'Send'}/>
            </View>
            <View style={{marginTop:height*.04,marginHorizontal:height*.04}}>
                <View style={{flexDirection:'row', justifyContent:'space-between',borderBottomWidth:1,paddingVertical:10}}>
                    <Text style={styles.boldText}>History</Text>
                    <Text style={styles.boldText}>Clear</Text>
                </View>
                <ScrollView style={{height: height*.2}}>
                    <FlatList
                        data={transactionHistory}
                        renderItem={({ item }) => (
                            <View style={{flexDirection:'row',justifyContent:'space-between',paddingVertical:10}}>
                                <Text style={styles.normalText}>{item.date}</Text>
                                <Text style={styles.normalText}>{item.amount}</Text>
                            </View>
                        )}
                        keyExtractor={item => item.id}
                    />
                </ScrollView>
            </View>
            <View style={{position:'absolute',bottom:30}}>
                <Text style={[styles.boldText,{textAlign:'center',fontSize:20}]}>Need to Know</Text>
                <Text style={styles.normalText}>1. Transactions will get 6 confirmations on the Blockchain</Text>
                <Text style={styles.normalText}>2. Transactions stays for only 45 days before becoming invalid</Text>
                <Text style={styles.normalText}>3. Transactions takes 20-30mins</Text>
            </View>
        </View>
    );
}
const styles = StyleSheet.create({
    rowContainer: {
        backgroundColor: '#4E97F5',
    },
    textInput:{
        borderBottomWidth:.5,
        // ,
        // paddingHorizontal:10,
        // paddingVertical: 16,
        paddingHorizontal: 16,
    },
    boldText:{
        fontWeight:'bold',
        fontSize:16, 
    },
    normalText:{
        fontSize:16,
    },
    icon: {
        marginRight: 5,
    },
    placeholderStyle: {
        fontSize: 16,
    },
    selectedTextStyle: {
        fontSize: 16,
    },
    iconStyle: {
        width: 20,
        height: 20,
    },
    inputSearchStyle: {
        height: 40,
        fontSize: 16,
    },
    button: {
        backgroundColor: "#5A45FF",
        color: "#FFFFFF",
        borderRadius: 2,
        paddingHorizontal: 16,
        paddingVertical: 12,
    },
    text: {
        color: "#FFFFFF",
        fontSize: 16,
        fontWeight: "600",
    },
    dropdown: {
        height: 50,
        borderColor: '#000',
        borderBottomWidth: 0.5,
        paddingHorizontal: 8,
        marginVertical: 20,
    },
});
export default MainPage;
```
When you implement this, you will get a nice design as shown below. 

![MainPage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65ectad4cbcoxw18r9hi.jpeg)
//=====================image===========================//
Now, let us install a couple of dependencies
```
npx expo install @react-native-async-storage/async-storage @walletconnect/client @walletconnect/react-native-dapp

```
After you have done this we do this
```
npm install react-native-get-random-values@1.8.0 react-native-randombytes@3.6.1 react-native-crypto@2.2.0
```
After successfully installing this, we need to do a small thing. In the package.json file, let's add a script to be executed.
```
    "postinstall": "rn-nodeify --hack --install process,crypto,events,constant,console,stream,url,util"

```
This is very essential because the  ```@wallectconnect/react-native-dapp`` needs crypto module which is only native to NodeJS and not React Native, running this will include it to your application.

Now let's finish up on the frontend functionality by adding the following functions
```
    const connectWallet =() => {
        return connector.connect();
    };
    const killSession =() => {
        setValue({wallet:0});

        return connector.killSession();
    };
    const sendButtonHandler = () => {
        console.log('Pressed');
        console.log('Value is: ',value)
        if (value.amount <5 && value.amount && value.receiver && value.wallet && connector.connected && ownerAddress) {
            Alert.alert('Warning!!','Are you sure you want to send this?',[
                {
                    text:'No',
                    onPress:() => {
                        console.log('No Pressed');
                    },
                    style:'cancel'
                },
                {
                    text:'Yes',
                    onPress:() => {
                        console.log('Yes Pressed');
                      
                    },
                    style:'destructive'
                }
            ])
            return;
        }
        Alert.alert('Error','Please fill all the fields correctly');
    };
    function connectButtonHandler(){
        console.log('Pressed',value.wallet)
        if(value.wallet===2){
            connectWallet();
        }
    }
    useEffect(() => {
        if(connector.connected){
            setOwnerAddress(connector.accounts[0]);
        }
    }, [connector.connected]);
    function Button({ onPress, label }) {
        return (
            <TouchableOpacity onPress={onPress} style={styles.button}>
                <Text style={styles.text}>{label}</Text>
            </TouchableOpacity>
        );
    }
    useEffect(() => {
        connectButtonHandler();
    }, [value.wallet]);
```
Now let we will be binding this to their respective buttons. The final code in the ***``Mainpage.jsx``*** is like this
[Final Code](https://github.com/OliverMengich/CryptoApp/blob/main/screens/MainPage.js)