A cryptocurrency wallet app built with React Native offers a user-friendly interface for managing digital assets. It is designed to facilitate the secure storage, management, and transaction of cryptocurrencies. A cryptocurrency wallet app provides functionalities such as Balance Tracking, Transaction Management, Conversion and Exchange, Transaction History, and User Profile, among others.

Playground
Note: This Section is to interact with the app which you are going to build.
Prerequisites
Step-by-Step Implementation
Step 1: Create a React Native Project
Now, create a project with the following command.
npx create-expo-app app-name --template
Note: Replace the app-name with your app name for example : react-native-demo-app
Next, you might be asked to choose a template. Select one based on your preference as shown in the image below. I am selecting the blank template because it will generate a minimal app that is as clean as an empty canvas in JavaScript.

It completes the project creation and displays a message: "Your Project is ready!" as shown in the image below.

Now go into your project folder, i.e., react-native-demo
cd app-nameProject Structure:

Step 2: Run Application
Start the server by using the following command.
npx expo startThen, the application will display a QR code.
- For the Android users,
- For the Android Emulator, press " a" as mentioned in the image below.
- For the Physical Device, download the " Expo Go " app from the Play Store. Open the app, and you will see a button labeled " Scan QR Code. " Click that button and scan the QR code; it will automatically build the Android app on your device.
- For iOS users, simply scan the QR code using the Camera app.
- If you're using a web browser, it will provide a local host link that you can use as mentioned in the image below.

Step 3: Start Coding
- Approach to Create a Cryptocurrency Wallet App:
- Users can view their profile at the user icon in the top right, which includes their name.
- The app displays the total wallet balance of different cryptocurrencies on the main screen.
- Users can perform actions such as sending cryptocurrencies, requesting them, and viewing transaction history using the corresponding buttons.
- The app provides a list of cryptocurrencies along with their names, balances, and icons.
- Users can scroll through the list to view their holdings and relevant details.
- Creating a fully working cryptocurrency wallet app is very long and complex work, so we have created only the homepage UI of the app.
Let's dive into the code in detail.
- Import libraries:
Import required libraries at the top of the file.
// Import React hooks and React Native components
import { useState, useEffect } from 'react';
import {
View, Text,
TouchableOpacity, FlatList,
StyleSheet
} from 'react-native';
// Import FontAwesome icons
import Icon from 'react-native-vector-icons/FontAwesome';
- StyleSheet:
Create a StyleSheet to style components like container, profileSection, profileName, etc.
// Styles for the app
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
profileSection: {
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'start',
marginBottom: 10,
},
profileName: {
marginLeft: 10,
fontSize: 16,
fontWeight: 'bold',
},
banner: {
backgroundColor: '#3498db',
padding: 16,
borderRadius: 8,
marginBottom: 16,
alignItems: 'center',
},
bannerText: {
fontSize: 18,
color: '#fff',
},
bannerBalance: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
marginTop: 8,
},
buttonsContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 16,
},
button: {
flex: 1,
backgroundColor: '#e0e0e0',
padding: 12,
borderRadius: 8,
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'center',
marginHorizontal: 4,
},
buttonIcon: {
marginRight: 6,
},
buttonDataContainer: {
marginBottom: 16,
padding: 12,
backgroundColor: '#f1f1f1',
borderRadius: 8,
},
buttonActionText: {
fontWeight: 'bold',
marginBottom: 6,
},
sectionTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
},
cryptoItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12,
borderBottomWidth: 1,
borderBottomColor: '#ddd',
},
cryptoIcon: {
marginRight: 12,
},
cryptoInfo: {
flexDirection: 'column',
},
cryptoName: {
fontSize: 16,
fontWeight: 'bold',
},
cryptoBalance: {
fontSize: 14,
color: '#555',
},
});
- User Profile Section:
This section includes,
- user-circle icon: Used to represent the user profile photo.
- User Name: Name of the user.
{/* User Profile Section */}
<View style={styles.profileSection}>
<TouchableOpacity>
<Icon name="user-circle" size={30} color="#3498db" />
</TouchableOpacity>
<Text style={styles.profileName}>User Name</Text>
</View>
- Wallet Banner Section:
This section includes,
- walletBalance: This state variable is used to store the total wallet balance.
- useEffect: This is used to calculate the total wallet balance whenever cryptocurrency changes.
- View component: It wrapped two Text components, one to indicate this section is about "Total Wallet Balance:" and the other is to display the total balance using walletBalance.
// State to store total wallet balance
const [walletBalance, setWalletBalance] = useState(0);
// Calculate total wallet balance whenever cryptoCurrencies change
useEffect(() => {
const totalBalance = cryptoCurrencies.reduce(
(sum, crypto) => sum + crypto.balance,
100 // Assume base balance of 100
);
setWalletBalance(totalBalance);
}, [cryptoCurrencies]);
{/* Wallet Banner showing total balance */}
<View style={styles.banner}>
<Text style={styles.bannerText}>Total Wallet Balance:</Text>
<Text style={styles.bannerBalance}>{walletBalance} BTC</Text>
</View>
- Buttons Sections:
This section includes,
- buttonAction & buttonData: These state variables are used to select the action and hold the data based on the selected action.
- handleButtonPress function: Handles the business logic user tap on any button.
- UI for Buttons: The UI is designedusing a View component having a Text component to indicate the action and a TouchableOpacity component to call the handleButtonPress function whenever the user taps on any button.
// State for the selected action: 'send', 'request', or 'history'
const [buttonAction, setButtonAction] = useState('');
// State to hold the data based on the selected action
const [buttonData, setButtonData] = useState(null);
// Handles what happens when user clicks Send, Request, or History
const handleButtonPress = (action) => {
switch (action) {
case 'send':
setButtonAction('Send');
setButtonData({
recipient: 'User name',
amount: 0.08,
currency: 'BTC',
});
break;
case 'request':
setButtonAction('Request');
setButtonData({
sender: 'SampleSender',
amount: 0.10,
currency: 'BTC',
});
break;
case 'history':
setButtonAction('Transaction History');
setButtonData([
{ id: 1, type: 'Sent', amount: 0.005, currency: 'BTC' },
{ id: 2, type: 'Received', amount: 0.01, currency: 'BTC' },
{ id: 3, type: 'Sent', amount: 0.015, currency: 'BTC' },
]);
break;
default:
break;
}
};
{/* Action Buttons */}
<View style={styles.buttonsContainer}>
{/* Send Button */}
<TouchableOpacity style={styles.button} onPress={() => handleButtonPress('send')}>
<Icon name="send" size={20} color="#3498db" style={styles.buttonIcon} />
<Text>Send</Text>
</TouchableOpacity>
{/* request Button */}
<TouchableOpacity style={styles.button} onPress={() => handleButtonPress('request')}>
<Icon name="arrow-up" size={20} color="#3498db" style={styles.buttonIcon} />
<Text>Request</Text>
</TouchableOpacity>
{/* history Button */}
<TouchableOpacity style={styles.button} onPress={() => handleButtonPress('history')}>
<Icon name="history" size={20} color="#3498db" style={styles.buttonIcon} />
<Text>History</Text>
</TouchableOpacity>
</View>
- Result Section:
This section includes,
- buttonData: This state variable is used to store the data based on the selected action.
- renderButtonData: It is used to render the UI of the result according to the selected button (Send, Request, or History)
- Calling renderButtonData in UI.
// State to hold the data based on the selected action
const [buttonData, setButtonData] = useState(null);
// Render the details based on selected button (Send, Request, or History)
const renderButtonData = () => {
if (!buttonData) return null;
// If data is an array (like history), map over each item
if (Array.isArray(buttonData)) {
return (
<View style={styles.buttonDataContainer}>
<Text style={styles.buttonActionText}>{buttonAction}</Text>
{buttonData.map((dataItem) => (
<Text key={dataItem.id}>
{dataItem.type}: {dataItem.amount} {dataItem.currency}
</Text>
))}
</View>
);
} else {
// If single object (like send or request)
return (
<View style={styles.buttonDataContainer}>
<Text style={styles.buttonActionText}>{buttonAction}</Text>
<Text>Recipient: {buttonData.recipient || buttonData.sender}</Text>
<Text>Amount: {buttonData.amount} {buttonData.currency}</Text>
</View>
);
}
};
{/* Conditional details shown based on selected action */}
{renderButtonData()}
- Crypto Currencies List Section:
This Section includes,
- CryptoCurrencies list: This is a static list of a map of cryptocurrencies with ID, name, balance, and icon as keys.
- renderItem: This function is used to render every item in the cryptocurrency list.
- Section Title: This Text Component, having text "Cryptocurrencies", is to indicate that the below list is about cryptocurrencies.
- FlatList: This component is used to display a list of cryptocurrencies.
// Static list of cryptocurrency data
const [cryptoCurrencies] = useState([
{ id: 1, name: 'Bitcoin', balance: 0.25, icon: 'bitcoin' },
{ id: 2, name: 'Ethereum', balance: 2.5, icon: 'circle' },
{ id: 3, name: 'Litecoin', balance: 5.0, icon: 'diamond' },
{ id: 4, name: 'Ripple', balance: 500, icon: 'exchange' },
{ id: 5, name: 'Cardano', balance: 3000, icon: 'credit-card' },
{ id: 6, name: 'Polkadot', balance: 10, icon: 'dot-circle-o' },
{ id: 7, name: 'Chainlink', balance: 50, icon: 'link' },
{ id: 8, name: 'Stellar', balance: 800, icon: 'star' },
{ id: 9, name: 'Uniswap', balance: 3, icon: 'university' },
{ id: 10, name: 'Dogecoin', balance: 1000, icon: 'paw' },
]);
// Render function for each crypto currency item in the list
const renderItem = ({ item }) => (
<View style={styles.cryptoItem}>
<Icon name={item.icon} size={30} color="#3498db" style={styles.cryptoIcon} />
<View style={styles.cryptoInfo}>
<Text style={styles.cryptoName}>{item.name}</Text>
<Text style={styles.cryptoBalance}>
{item.balance} {item.name}
</Text>
</View>
</View>
);
{/* Section Title */}
<Text style={styles.sectionTitle}>Cryptocurrencies</Text>
{/* List of cryptocurrencies */}
<FlatList
data={cryptoCurrencies}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
contentContainerStyle={{ paddingBottom: 100 }}
/>
Now, wrap all design code with a View component, return it from the App component, and place all methods and useStates within the App component. Ensure to export the App.
Complete Source Code
App.js:
// Import React hooks and React Native components
import { useState, useEffect } from 'react';
import {
View, Text,
TouchableOpacity, FlatList,
StyleSheet
} from 'react-native';
// Import FontAwesome icons
import Icon from 'react-native-vector-icons/FontAwesome';
// Main functional component for the app
const CryptoWalletApp = () => {
// State to store total wallet balance
const [walletBalance, setWalletBalance] = useState(0);
// Static list of cryptocurrency data
const [cryptoCurrencies] = useState([
{ id: 1, name: 'Bitcoin', balance: 0.25, icon: 'bitcoin' },
{ id: 2, name: 'Ethereum', balance: 2.5, icon: 'circle' },
{ id: 3, name: 'Litecoin', balance: 5.0, icon: 'diamond' },
{ id: 4, name: 'Ripple', balance: 500, icon: 'exchange' },
{ id: 5, name: 'Cardano', balance: 3000, icon: 'credit-card' },
{ id: 6, name: 'Polkadot', balance: 10, icon: 'dot-circle-o' },
{ id: 7, name: 'Chainlink', balance: 50, icon: 'link' },
{ id: 8, name: 'Stellar', balance: 800, icon: 'star' },
{ id: 9, name: 'Uniswap', balance: 3, icon: 'university' },
{ id: 10, name: 'Dogecoin', balance: 1000, icon: 'paw' },
]);
// State for the selected action: 'send', 'request', or 'history'
const [buttonAction, setButtonAction] = useState('');
// State to hold the data based on the selected action
const [buttonData, setButtonData] = useState(null);
// Calculate total wallet balance whenever cryptoCurrencies change
useEffect(() => {
const totalBalance = cryptoCurrencies.reduce(
(sum, crypto) => sum + crypto.balance,
100 // Assume base balance of 100
);
setWalletBalance(totalBalance);
}, [cryptoCurrencies]);
// Handles what happens when user clicks Send, Request, or History
const handleButtonPress = (action) => {
switch (action) {
case 'send':
setButtonAction('Send');
setButtonData({
recipient: 'User name',
amount: 0.08,
currency: 'BTC',
});
break;
case 'request':
setButtonAction('Request');
setButtonData({
sender: 'SampleSender',
amount: 0.10,
currency: 'BTC',
});
break;
case 'history':
setButtonAction('Transaction History');
setButtonData([
{ id: 1, type: 'Sent', amount: 0.005, currency: 'BTC' },
{ id: 2, type: 'Received', amount: 0.01, currency: 'BTC' },
{ id: 3, type: 'Sent', amount: 0.015, currency: 'BTC' },
]);
break;
default:
break;
}
};
// Render function for each crypto currency item in the list
const renderItem = ({ item }) => (
<View style={styles.cryptoItem}>
<Icon name={item.icon} size={30} color="#3498db" style={styles.cryptoIcon} />
<View style={styles.cryptoInfo}>
<Text style={styles.cryptoName}>{item.name}</Text>
<Text style={styles.cryptoBalance}>
{item.balance} {item.name}
</Text>
</View>
</View>
);
// Render the details based on selected button (Send, Request, or History)
const renderButtonData = () => {
if (!buttonData) return null;
// If data is an array (like history), map over each item
if (Array.isArray(buttonData)) {
return (
<View style={styles.buttonDataContainer}>
<Text style={styles.buttonActionText}>{buttonAction}</Text>
{buttonData.map((dataItem) => (
<Text key={dataItem.id}>
{dataItem.type}: {dataItem.amount} {dataItem.currency}
</Text>
))}
</View>
);
} else {
// If single object (like send or request)
return (
<View style={styles.buttonDataContainer}>
<Text style={styles.buttonActionText}>{buttonAction}</Text>
<Text>Recipient: {buttonData.recipient || buttonData.sender}</Text>
<Text>Amount: {buttonData.amount} {buttonData.currency}</Text>
</View>
);
}
};
return (
<View style={styles.container}>
{/* User Profile Section */}
<View style={styles.profileSection}>
<TouchableOpacity>
<Icon name="user-circle" size={30} color="#3498db" />
</TouchableOpacity>
<Text style={styles.profileName}>User Name</Text>
</View>
{/* Wallet Banner showing total balance */}
<View style={styles.banner}>
<Text style={styles.bannerText}>Total Wallet Balance:</Text>
<Text style={styles.bannerBalance}>{walletBalance} BTC</Text>
</View>
{/* Action Buttons */}
<View style={styles.buttonsContainer}>
<TouchableOpacity style={styles.button} onPress={() => handleButtonPress('send')}>
<Icon name="send" size={20} color="#3498db" style={styles.buttonIcon} />
<Text>Send</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={() => handleButtonPress('request')}>
<Icon name="arrow-up" size={20} color="#3498db" style={styles.buttonIcon} />
<Text>Request</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={() => handleButtonPress('history')}>
<Icon name="history" size={20} color="#3498db" style={styles.buttonIcon} />
<Text>History</Text>
</TouchableOpacity>
</View>
{/* Conditional details shown based on selected action */}
{renderButtonData()}
{/* Section Title */}
<Text style={styles.sectionTitle}>Cryptocurrencies</Text>
{/* List of cryptocurrencies */}
<FlatList
data={cryptoCurrencies}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
contentContainerStyle={{ paddingBottom: 100 }}
/>
</View>
);
};
// Styles for the app
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
profileSection: {
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'start',
marginBottom: 10,
},
profileName: {
marginLeft: 10,
fontSize: 16,
fontWeight: 'bold',
},
banner: {
backgroundColor: '#3498db',
padding: 16,
borderRadius: 8,
marginBottom: 16,
alignItems: 'center',
},
bannerText: {
fontSize: 18,
color: '#fff',
},
bannerBalance: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
marginTop: 8,
},
buttonsContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 16,
},
button: {
flex: 1,
backgroundColor: '#e0e0e0',
padding: 12,
borderRadius: 8,
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'center',
marginHorizontal: 4,
},
buttonIcon: {
marginRight: 6,
},
buttonDataContainer: {
marginBottom: 16,
padding: 12,
backgroundColor: '#f1f1f1',
borderRadius: 8,
},
buttonActionText: {
fontWeight: 'bold',
marginBottom: 6,
},
sectionTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
},
cryptoItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12,
borderBottomWidth: 1,
borderBottomColor: '#ddd',
},
cryptoIcon: {
marginRight: 12,
},
cryptoInfo: {
flexDirection: 'column',
},
cryptoName: {
fontSize: 16,
fontWeight: 'bold',
},
cryptoBalance: {
fontSize: 14,
color: '#555',
},
});
// Export the component
export default CryptoWalletApp;