A custodial wallet is a type of cryptocurrency wallet where the user's private keys are held by a third-party custodian. This can be a convenient option for users new to cryptocurrencies who may not feel comfortable managing their private keys. In this article, we'll walk through the process of building a custodial wallet with Python.
However, we will use an API in this implementation. So, before we get started, let's look at what an API is.
What is an API
API stands for application programming interface; it is the medium by which digital information is sent and received between software systems.
Prerequisites
Step 1:
BlockIO provides accessible services that can be leveraged to create a custodial Bitcoin wallet. Sign up on block.io and set up your account; upon completion, you will be given your API-KEY and SECRET-KEY.
Note: We will be using bitcoin test net during this development
Step 2:
To get started, we'll need to install a few Python libraries. Open your command prompt or terminal window and create your project directory using the below code
mkdir bitcoin_custodial_wallet
"bitcoin_custodial_wallet" is the name of the folder; you can change the above project name to your desired project name.
Change to the directory with the below code
cd bitcoin_custodial_wallet
Now, use the code below to install the necessary libraries.
pip install jmespath
pip install block-io
Now, let's jump into coding our wallet
As mentioned above, a custodial wallet does not require users to manage their private keys. What we are concerned with is the following:
The user's name should be associated with their Bitcoin wallet address
Users should be able to send Bitcoin from their wallet
Users should be able to receive Bitcoin in their wallet
Users should see their available Bitcoin balance
Coding The Wallet
First, create a Python file. We will import the necessary libraries using the below code.
Note: All the codes should be in a single Python file.
from block_io import BlockIo
import jmespath
import json
Now, to use the BlockIO API, we need to initialize it. To do so, use the below code
version = 2 #API version
block_io = BlockIo('Api-Key', "Secret-Key", version)
Now we dive into writing the code.
Create Bitcoin Wallet Address Associated With a Name
def username(name):
return name
Name = username(input("Enter Username: "))
#greet user using created name
greet = ("HELLO" " " + username(name=Name))
print(greet)
# Generate a new wallet address with name
def gen_wallet(_name):
generate_wa = block_io.get_new_address(label=_name)
return generate_wa
gen_Wa = gen_wallet(Name)
print("++++++++++++++++Welcome!" + username(name=Name) + " " + "Your Account Details are below+++++++++")
print(gen_Wa)
In the above code, we defined two functions: one for the username and another for generating a wallet that will be mapped to the username. The first function (username)
takes the user's desired username and uses that name in the second function (gen_wallet)
. The function gen_wallet
computes a Bitcoin wallet that is mapped to the name argument given by the user using this call (block_io.get_new_address(label=_name))
.
Receive Bitcoin
#get wallet address by username
def get_wallet_by_name(fill):
lol = json.dumps(block_io.get_address_by_label(label=(fill)))
lol_ = json.loads(lol)
wallet_addy = jmespath.search("data.address", lol_)
return wallet_addy + "
g_w_name = (get_wallet_by_name(input("Please Enter your Username: ")))
print(g_w_name + " This is your wallet address")
The above code gets the wallet address associated with the user's name using block_io.get_address_by_label(label=(fill))
. To fetch the precise address, the response to the call is searched using jmespath.search
the jmespath.search
function takes two arguments: what and where to search, and in this case, "data.address and lol_".
To test if the wallet can receive bitcoin, copy the wallet displayed as your wallet address and navigate to any bitcoin test net faucet of your choice. In my case, I used the testnet-faucet, which takes roughly 45 minutes to dispense to your wallet.
Display Available Bitcoin Balance
def get_wallet_balance_by_addy(wallet_add):
gadd = block_io.get_address_balance(address=(wallet_add))
gadd_ = jmespath.search("data.available_balance", gadd)
return gadd_
g_wallet = (get_wallet_balance_by_addy(input("Please Enter Your Address: ")))
print(g_wallet)
Here, we call block_io.get_address_balance(address=(wallet_add))
. Using this call, we can get the available bitcoin balance in a user's wallet by passing the user's wallet address as the argument and searching the response with the jmespath.search()
command.
Send Bitcoin
Before we proceed to define the code for this aspect, we will need to accept two inputs from the users:
The amount of bitcoin to be sent out of the wallet
The address to receive the bitcoin
#amount to be sent
Amount_to = (input("Enter amount to send: "))
#address to send bitcoin to
addy_to = (input("Address to send to: "))
These two inputs are passed to the function we are going to define to compute the transaction.
def send_transfer(amount, recipient_address):
_amount = amount
to_address = recipient_address
preparetx = block_io.prepare_transaction(amounts=_amount, to_addresses=to_address)
signtx = block_io.create_and_sign_transaction(preparetx)
response = block_io.submit_transaction(transaction_data=signtx)
return response
send_t = send_transfer(Amount_to, addy_to)
status = jmespath.search("status", send_t)
if status == "success":
print("Transaction sent ✅🚀")
else:
print("not successful❌")
To be able to send bitcoin out of the wallet, we need to pass the following steps:
- Prepare the transaction
- Sign the transaction
- Submit the transaction
To prepare the transaction, we call block_io.prepare_transaction(amounts=_amount, to_addresses=to_address)
which takes the amount to be sent and the address to receive the bitcoin.
Next is to sign the transaction; signing the transaction means you approve the bitcoin leaving your wallet. This is done using your wallet's private key, but here we will use this callblock_io.create_and_sign_transaction(preparetx)
. The call takes the prepared transaction as an argument and signs the transaction using your wallet's private key.
Finally, we submit the transaction for mining with this call block_io.submit_transaction(transaction_data=signtx)
.
Additionally, we add a condition to check if the transfer is successful, if it is not, it prompts the sender with a not successful message.
Source Code
The source code can be found here on GitHub.
Summary
Congratulations! We have successfully built a custodial bitcoin wallet. In this article, we have created a custodial bitcoin wallet that can receive, send, and store bitcoin.
Top comments (0)