• Sun. Jun 30th, 2024

Developers’ Guide: How to Build a Crypto Wallet Using Python

In the dynamic world of cryptocurrencies, the ability to interact with blockchain networks is of utmost importance. One of the key components facilitating this interaction is the crypto wallet.

In this tutorial, I will be demonstrating how to build a basic crypto wallet with Python, designed to provide a simple and user-friendly interface for interacting with the Ethereum network. We’ll be using the Ethereum network for this demo due to its popularity and wide usage in the crypto space. Our wallet will be ERC-20 token-compatible, a standard for most projects built on Ethereum.

Let’s first review the key functionalities of our crypto wallet.

Level of Functionality

We’ll kickstart the process by determining our crypto wallet’s key functionalities:

  • Generating and Storing Keys: The wallet can generate a new pair of public and private keys. The public key, also known as the wallet address, is used to receive funds, while the private key is used to sign transactions.
  • Displaying Balance: The wallet can display the user’s balance in Ether, based on the input address and contract, and show historical market chart data for a contract.
  • Sending and Receiving Transactions: The wallet can send Ether to other Ethereum addresses and automatically receives incoming transactions. Transaction details are signed with the user’s private key and sent via the Infura API. The transaction hash, used to track the transaction, is returned. Test Ether (for test networks) or real Ether (for the Ethereum mainnet) is needed to fully test this functionality.
  • Viewing Market Chart: The application can fetch and display the market chart data for a specific contract in USD. It uses CoinGecko API to get the market chart data.

Disclaimer: This is a basic wallet and does not have advanced features such as staking, swapping, or interacting with decentralized applications (dApps).

The wallet will use web3.py, a Python library that allows interaction with the Ethereum blockchain through JSON-RPC, and the Infura API, a service that provides access to Ethereum nodes, to connect to the network and perform transactions.

The front-end of the wallet will run on a web browser and will use HTML, CSS, and JavaScript to create the interface and functionality. The front-end will communicate with the back-end, which will be written in Python, using Flask, a web framework that allows building web applications.

Prerequisites and Installing the Required Python Libraries

Before building, there are a few prerequisites that you need to have:

  • Python: Python should be installed on your system, as we will be using Python to write our back-end code. You can download it from the official Python website.
  • Flask: Flask is a lightweight web framework for Python, and will be used to create our web application. You can install Flask using pip, which is a package manager for Python.
  • Web3.py: Web3.py is a Python library for interacting with Ethereum. It’s a crucial part of our project as it allows us to generate accounts and interact with the Ethereum blockchain. You can install web3.py using pip.
  • Infura Account: Infura is a service that provides access to the Ethereum network. You will need to create an account on Infura and create a new project to get your Infura Project ID.
  • CoinGecko API: We will be using the CoinGecko API to fetch the market chart data for cryptocurrencies. The CoinGecko API has a free Demo plan accessible to all users with a 30 calls/min rate limit and a monthly cap of 10,000 calls. Sign up for a CoinGecko account and apply for the Demo plan to generate your complimentary API key.
  • Text Editor or IDE: You will need a text editor or an Integrated Development Environment (IDE) to write your code. Some popular choices include Sublime Text, Atom, Visual Studio Code, and PyCharm.

While not mandatory, having a basic understanding of how cryptocurrencies and the Ethereum blockchain work will help understand the code and the workings of the crypto wallet.

Before running the code, you also need to install the necessary Python libraries. Here’s how you can do it:

  1. Open your terminal or command prompt.
  2. Install Flask by typing the following command and pressing enter:

    pip install flask

  3. Install web3.py by typing the following command and pressing enter:

pip install web3

  1. Install requests by typing the following command and pressing enter:

pip install requests

💡Pro-tip: Please note that if you’re using a system with both Python 2 and Python 3, you might need to use pip3 instead of pip.


How to Build a Crypto Wallet on Ethereum

Developers can build a crypto wallet on Ethereum by using Python for both the back-end (integration with web3 libraries for blockchain interaction) and front-end (Flask, for the user interface). Here is an illustrative example of the implementation:

from aiohttp import request
from flask import Flask, jsonify, render_template, session

from web3 import Web3

import requests

import json

app = Flask(__name__)

infura_url = 'https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID '

web3 = Web3(Web3.HTTPProvider(infura_url))

app.config['SECRET_KEY'] = 'your-secret-key'  # replace with your secret key

@app.route('/new_account', methods=['GET'])

def new_account():

    account = web3.eth.account.create('YOUR_PASSWORD')

    session['account'] = {

        'privateKey': account.key.hex(),

        'address': account.address

    }

    return jsonify(session['account'])

with open('erc20_abi.json') as f:

    erc20_abi = json.load(f)

@app.route('/balance/<contract_address>', methods=['GET'])

def get_balance(contract_address):

    address = session.get('account').get('address')

    checksum_address = Web3.to_checksum_address(address)

    print(checksum_address)

    contract = web3.eth.contract(address=contract_address, abi=erc20_abi)

    balance = contract.functions.balanceOf(checksum_address).call()

    return jsonify({'balance': balance})

@app.route('/send_transaction', methods=['POST'])

def send_transaction():

    data = request.get_json()

    nonce = web3.eth.getTransactionCount(session['account']['address'])

    txn_dict = {

            'to': data['to'],

            'value': web3.toWei(data['amount'], 'ether'),

            'gas': 2000000,

            'gasPrice': web3.toWei('40', 'gwei'),

            'nonce': nonce,

            'chainId': 3

    }

    signed_txn = web3.eth.account.signTransaction(txn_dict, session['account']['privateKey'])

    txn_hash = web3.eth.sendRawTransaction(signed_txn.rawTransaction)

    return jsonify({'transaction_hash': txn_hash.hex()})

@app.route('/market_chart/<contract_address>/<days>', methods=['GET'])

def get_market_chart(contract_address, days):

    api_key = 'coingecko_api_key' # replace this with your own API key

    response = requests.get(f'https://api.coingecko.com/api/v3/coins/ethereum/contract/{contract_address}/market_chart?vs_currency=usd&days={days}&api_key={api_key}')

    market_chart = response.json()

    return jsonify(market_chart)

@app.route('/')

def home():

    return render_template('index.html')

if __name__ == '__main__':

    app.run(debug=True)

This Flask application has four routes:

  1. /new_account: Generates a new Ethereum account and returns the private key and address.

  2. /balance/<contract_address>: Fetches the balance of the newly created account address and contract_address using the Web3 package and returns it.

  3. /send_transaction: This endpoint allows the wallet to send Ether to other Ethereum addresses. It takes the recipient’s address and the amount to be sent as input, signs the transaction with the user’s private key and sends it via the Infura API. The transaction hash is returned, which can be used to track the transaction on the Ethereum network. 

  4. /market_chart/<contract_address>/<days>: Fetches the market chart data for the given contract address over the specified number of days using the CoinGecko API and returns it. The contract_address is the address of the ERC20 contract and days is the number of past days to fetch the market chart data.

💡Pro-tip: In Ethereum, addresses returned by this package are checksum addresses, which contain a mix of uppercase and lowercase letters. The checksum validates the address. Errors occur with incorrect checksums. To bypass the checksum check, use all lower- or uppercase letters in the address.

You can run this application locally by executing the Python script, and accessing the routes in your web browser or using a tool like curl or Postman.

Remember to replace YOUR_INFURA_PROJECT_ID and YOUR_PASSWORD with your actual Infura project ID (or API key) and a secure password. Always remember to keep your private keys and passwords secure and never share them with anyone!

Referencing the HTML and ERC20 Code

The code for this project is quite extensive, involving both HTML for the user interface and ERC20 token interactions on the Ethereum blockchain. For a detailed view of the code, please refer to the provided Github repository.

The repository contains all the necessary files and instructions to understand the workings of the project. It includes the HTML code for the user interface and the Python code for interacting with ERC20 tokens using the Web3 library. The repository serves as a comprehensive guide to understanding and running the project.

Run the Wallet in Web Browser

Let’s run our wallet in the browser, following these steps:

  1. Save the code in a file named app.py.
  2. Open your terminal or command prompt.
  3. Navigate to the directory where you saved app.py.
  4. Run the file by typing the following command and pressing enter:python app.py
  5. After running the command, you should see an output indicating that your Flask application is running. You can then open your web browser and navigate to http://localhost:5000 to interact with your application

The above program is tested with 0x6B175474E89094C44Da98b954EedeAC495271d0F, which is the contract address for DAI Stablecoin. The balance displayed is 0, indicating the newly created account doesn’t hold any DAI tokens. The market chart data is displayed using CoinGecko API and represents the price history of DAI in USD.

For transactions, the user can enter the recipient’s address and the amount of Ether to be sent. When the Send Transaction button is clicked, a POST request is made to the /send_transaction endpoint with the recipient’s address and the amount as data.

Advanced Crypto Wallet Functionality and Further Considerations

While this guide covers only basic crypto wallet development, developers who might want to expand wallet functionalities can consider the following:

  • Token Swapping: Implement functionality to swap one type of token for another. This could involve integrating with a decentralized exchange protocol like Uniswap or SushiSwap.
  • Staking and Yield Farming: Allow users to stake their tokens or provide liquidity to earn rewards. This would involve interacting with various DeFi protocols.
  • NFT Support: Expand the wallet to support Non-Fungible Tokens (NFTs). This would allow users to hold and transfer unique digital assets.
  • Build a Crypto dashboard that can be utilized with CoinGecko Demo API features are:
    • Crypto Price Alerts: Notify the user when the price of a crypto asset reaches a certain level and display it on the dashboard using the /simple/price endpoint.
    • Crypto News and Trends: Display the latest news, trending coins, and popular categories from the crypto space on the dashboard using the /search/* and /coins/categories/* endpoints.
    • Crypto Market Data: Provide the user with various market data such as market cap, volume, liquidity, dominance, and sentiment on the dashboard using the /global/* and /coins/markets/* endpoints. 

You can also use a library like Plotly or Dash to create interactive charts and graphs for your dashboard.

Remember, developing advanced features requires a deep understanding of Ethereum, smart contracts, and the various protocols you’ll be interacting with. Always prioritize the security of your users’ funds and adhere to best practices in the blockchain industry.


Conclusion

Building a basic crypto wallet for the Ethereum network using the Web3 Python library and CoinGecko API is a great way to understand and analyze how blockchain transactions work. This wallet can serve as a foundation for more complex applications, such as wallets with staking or swapping features, support multiple networks, or display NFT data.

Crypto developers and projects who want access to more API endpoints and greater data depth may consider subscribing to the CoinGecko Analyst API.

Get Richer Crypto Data API


Interested in more API resources? This extensive DEX Data API guide will walk you through how to get market data for a liquidity pool, access on-chain data for DEX-traded tokens and more.