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
- React Native knowledge
- 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.
//=====================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
is like this
Mainpage.jsx
Final Code
Top comments (0)