Open In App

Create a Cryptocurrency wallet using React-Native

Last Updated : 01 Jun, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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.

Create-a--Crypto-currency-wallet-using_


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-name

Project Structure:

Step 2: Run  Application

Start the server by using the following command.

npx expo start

Then, 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.

JavaScript
// 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.

JavaScript
// 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.
JavaScript
{/* 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.
JavaScript
// 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.
JavaScript
// 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.
JavaScript
// 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.
JavaScript
// 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:

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;

Output:


Similar Reads