Build Your First Stellar App Using Python and Flask Pt. 1

Kolten
Stellar Community
Published in
10 min readNov 2, 2020

--

This is part 1 of a 3 part series.

It’s been a while since I sat down and wrote a tutorial, but with all the new Stellar Questers pouring in it seemed like good timing. If you’re new to Stellar and have been looking for an easy way to get your hands dirty, this is the tutorial for you!

Throughout this tutorial series we’ll be building a simple web app using Python, Flask, and the Python Stellar SDK that:

  • Takes your public address as input
  • Reads and displays your balances
  • Lets you generate a transaction to send a Path Payment from XLM to some asset for which you have a balance
  • Lets you sign that transaction using Albedo

My goal is to help you build your first Stellar app that can retrieve data from the network, construct transactions, and securely sign transactions using Albedo.

Quick aside: I’m not an engineer. I just make stuff that kinda works. That’s what we’ll be doing here. So don’t take anything you see in this tutorial as best practice, but as a starting point to further your learning!

Before We Begin

I’m going to assume you have some prerequisite knowledge in this tutorial series because it would be too long otherwise. I expect you to have most of the Stellar basics down, along with some understanding of Python, Flask, and maybe HTML. If you don’t, you’ll still be able to make it through the tutorial, but some parts might be confusing.

First things first:

The Github repository contains a requirements.txt file and a skeleton application that will save us both a ton of time. Once you’ve finished those two steps, you’re ready to begin!

Setting the Stage

Take the Github directory you downloaded and move that folder (first-stellar-app-main) to your Desktop. Next, open your command line and navigate into the folder:

$ cd Desktop

$ rename first-stellar-app-main first-app (rename the folder to something short)

$ cd first-app

Once in your first-app folder, create a virtual environment—this will make it much easier to manage the packages we need for this project. Run the following command in your command line: $ virtualenv env. This creates a virtual environment called env. If everything went according to plan you should notice a new folder inside first-app named env.

Head back to your command line and enter this command: env\Scripts\activate.bat (Windows) or source env/bin/activate (Linux/MacOS). After you run it, your command line should look something like this:

If so, you’re inside your virtual environment! Next, you can install the required packages for this series with pip install -r requirements.txt. This step might take a bit, but you should see a bunch of packages start installing like you entered the matrix — you’ll need these!

Create an Account

After you’ve installed the necessary packages, we need to set up an account on the Stellar test network that you’ll use throughout this series. Fortunately it’s pretty easy :)

Head over to the Stellar Laboratory (for test net) and navigate to the Create Account tab. Once you’re there, click Generate Keypair, copy your new Public Key, and paste it into the Friendbot: Fund a test network account field. After you’ve pasted your public key, click Get test network lumens. Here’s what you should be seeing now:

If your screen matches mine, congrats! You now have 10,000 test net XLM. Make sure to save your public key and your secret key somewhere like a .txt file. This is only okay on test net, please do not do this with main network keys.

🗒 Note: Stellar was made to support digital representations of any currency, but it also has its own built-in token, called the lumen (XLM), created to fill a special role in the network. By design, Stellar requires that each account hold a small number of lumens at all times. Lumens are also used to pay transaction fees on the network.

Next we’ll have to set up some trust lines to assets with active markets on test net. Before an account can hold an asset another account issues, it has to establish a trustline, which is a persistent account-level ledger entry created with a change_trust operation. A trustline is an explicit opt-in to hold a particular token, so it specifies both asset code and issuer.

One way to do this is to head over to StellarExpert’s test net markets tab and pick one or two “active” assets:

Instead, I’ll be choosing an asset called HACK that has an available market.

To set up the trustlines, head over to the Build Transaction tab on the Stellar Laboratory, input your public key as the Source Account and click Fetch sequence number. It should look like the following:

Then scroll down to Operation Type and start building out a change_trust operation. To do this, enter the asset code and the issuing account’s public key:

After adding your change_trust operation, scroll down to click Sign in transaction signer, paste your secret key into the Add Signer field, and scroll down to Submit in transaction submitter. Once you’re on the transaction submitter page, click Submit Transaction and you should see your transaction go through:

Phew, I know. That was a lot of steps, we won’t need to do it again for the rest of the series. Unless you lose your public and secret key… so don’t do that! Now that your account is set up, we can start building the application.

Getting Started

If you’re awesome at following directions, you have a folder called first-app sitting on your desktop. It should include: env, stellar-app, and requirements.txt.

Revisiting your command line, which should still be inside the first-app folder:

Type the following commands (Windows <> Linux/MacOS):

  • set FLASK_APP=stellar-app or export FLASK_APP=stellar-app
  • set FLASK_ENV=development or export FLASK_ENV=development

The first command lets Flask know where your application is and the second command sets your Flask server to debug mode. Debug mode prevents you from needing to reload your Flask server every time you make a code change.

Next, type flask run into your command line and run it. Once you do this you should see Running on http://127.0.0.1:5000/ (Press CTRL+C to quit). Copy http://127.0.0.1:5000/ and visit it in your browser — like a normal website. You should see the app magically appear:

Please, please. Hold the applause. I’m not accepting any web design rewards at this time. That said: If you’ve made it this far, you’ve done everything right! You might notice that pasting your public key and clicking Submit doesn’t do anything special right now, but we’re about to fix that.

Adding a Pinch of Stellar

We’re finally ready to start reading data from the Stellar network! In this section we’ll be adding the functionality to read and display the balances associated with a Stellar public key.

🗒 Note: In this section we’ll be interacting with an API called Horizon. This API serves as a bridge between Stellar apps and Stellar Core. Stellar-based projects use Horizon to submit transactions, query an account balance, or stream events like transactions to an account.

Inside the first-app > stellar-app folder you’ll find a file called __init__.py — that’s where the application lives. Open up __init__.py in an editor of your choice and at the top of the file you’ll find the following code:

accounts_url will be a global variable that we use to store the URL for the Horizon Accounts endpoint. Accounts are the central data structure in Stellar. They hold balances, sign transactions, and issue assets. All entries that persist on the Stellar ledger are owned by a particular account. The Accounts endpoint will let us grab information about a specific account — we’ll need that later.

Change the # (keep quotes) after account_url to https://horizon-testnet.stellar.org/accounts/{}. The curly braces {} will allow us to add parameters to the URL later.

Next we’ll need to fill in the server variable. server will store a Server object implemented by the Python Stellar SDK. Server handles the network connection to a Horizon instance and exposes an interface for requests to that instance. We’ll want to establish a connection to the test net Horizon instance.

Change the ‘#’ (remove the quotes) after server to Server(horizon_url='https://horizon-testnet.stellar.org') to create the test net Server object.

Now for path_url. In our application we’ll be using one of Stellar’s coolest features: Path Payments. Path Payments allow users to send an asset and have it converted into a different asset before arriving at its destination. I send dollars; you receive euros.

They also work when used in a circular fashion. You can simply send a path payment to yourself (from asset A to asset B) and this will have the same effect as making a trade. That’s how we’ll be using them in this application!

path_url will store the URL for Horizon’s Paths endpoint. Paths provide us with information about potential path payments. A path can then be used to populate the necessary fields for a path payment operation — which we’ll use later!

Change the # after path_url (keep quotes) to https://horizon-testnet.stellar.org/paths/strict-send?destination_assets={}%3A{}&source_asset_type=native&source_amount={}. Remember: The curly braces allow us to easily add parameters to the URL.

Making it Work

Just below the URL variables, you’ll notice code that looks something like this:

If you’re unfamiliar with Flask, create_app() functions as an application factory. Inside, app = Flask(__name__, instance_relative_config=True) creates a Flask instance and __name__ tells the app where the Python module is located while instance_relative_config=True tells the app that configuration files are relative to the instance folder.

The next line, app.secret_key = ‘super secret key’, sets a secret key which is used to cryptographically sign cookies in a web session. We’ll use Sessions to pass data between pages in our Flask app.

Don’t touch any of this code.

After the Flask configuration you’ll notice the index() function with app.route('/') above it. This is what’s known as a route() decorator — which binds a function to a URL. In this case it binds index() to the home page of our app and returns index.html (the homepage you saw earlier).

Don’t touch this code either!

From this point on, I’ll skip the Flask explainers and get to the meat of the code. This is to save time and keep the focus on Stellar.

Now, with the warnings out of the way, scroll down a bit further and look for the following code:

The account() function allows us to get and present information about a public key’s balances on Stellar. It achieves this by taking the public key submitted in the HTML form on our app’s home page and sending a get request to the accounts_url variable we set earlier. It then renders that information in account.html.

To make the account() function work, set the r variable as follows:

r = requests.get(accounts_url.format(pub_key))

accounts_url.format(pub_key) adds a public key input to the end of the account_url variable. This is where those curly braces {} come in handy.

Then, decode the request in JSON format:

json_obj = r.json()

Lastly, pass json_obj into session[‘balances’]:

session[‘balances’] = json_obj

Decoding the Accounts endpoint request in JSON makes the account data much easier to access, while storing that JSON object in the session variable balances makes it accessible throughout the application.

When you call the Accounts endpoint, it returns a response like this:

You can see that the response contains balances and a host of other relevant information about an account — most of which will not be used in this tutorial series. For this tutorial we’ll mostly care about an account’s balances.

Test it Out

With your variables filled out, your ready to test the application! If you didn’t close your command line and your Flask app is still pulled up on http://127.0.0.1:5000/: Hit refresh, paste your public key into the form, and click Submit.

It should take you to account.html and show you your balances!

You can now enter any test net public key into the HTML form on index.html and see the account’s balances — try it out. The good news? We have way cooler functionality to add in Parts 2 and 3 of this series.

🗒 Note: If your Flask app is no longer running, scroll up and revisit the instructions in the Getting Started section. At this stage you should see a high XLM balance with 0 balances for any assets you set trustlines for.

What’s Next

Congratulations! You’ve finished Part 1 of this tutorial series. So far you’ve learned:

  • How to set up and fund a Stellar test network account
  • How to set trustlines for assets on Stellar
  • How to use the Horizon API to get balances of an account

That means we’ve checked two boxes on our series list:

  • Takes your public address as input ✔️
  • Reads and displays your balances ✔️
  • Lets you generate a transaction to send a Path Payment from XLM to some asset for which you have a balance ⬜
  • Lets you sign that transaction using Albedo

In Part 2 of this series (to be released soon), we’ll tackle the third item on that list and you’ll learn how to:

  • Use Horizon to search for Paths between assets
  • Construct a Path Payment transaction

If you have any questions or suggestions for this tutorial series, please reach out on Twitter!

--

--