Welcome to Polaris

To get a SEP-24 anchor server running quickly, see the tutorial.

The documentation below outlines the common set up needed for any Polaris deployment, but each SEP implementation has its own configuration and integration requirements. These requirements are described in the documentation for each SEP.

What is Polaris?

Polaris is an extendable django app for Stellar Ecosystem Proposal (SEP) implementations maintained by the Stellar Development Foundation (SDF). Using Polaris, you can run a web server supporting any combination of SEP-1, 6, 10, 12, 24, and 31.

While Polaris handles the majority of the business logic described in each SEP, there are pieces of functionality that can only be implemented by the developer using Polaris. For example, only an anchor can implement the integration with their partner bank.

This is why each SEP implemented by Polaris comes with a programmable interface, or integration points, for developers to inject their own business logic.

Polaris is completely open source and available on github. The SDF also runs a reference server using Polaris that can be tested using our demo client.

Installation and Configuration

These instructions assume you have already set up a django project. If you haven’t, take a look at the Django docs. It also assumes you have a database configured from the project’s settings.py.

First make sure you have cd’ed into your django project’s main directory and then run

pip install django-polaris

Settings

Add the following to INSTALLED_APPS in settings.py.

INSTALLED_APPS = [
    ...,
    "corsheaders",
    "rest_framework",
    "polaris",
]

Add CorsMiddleware to your settings.MIDDLEWARE. It should be listed above other middleware that can return responses such as CommonMiddleware.

MIDDLEWARE = [
    ...,
    'corsheaders.middleware.CorsMiddleware',
    ...
]

Polaris will now accept requests from all origins to its endpoints. It does this by adding corsheaders signal that checks the request URI. However this does not change the CORS policy for any other endpoint on the server. You can change this functionality using the settings listed in the corsheaders documentation.

Ensure BASE_DIR is defined in your project’s settings.py. Django adds this setting automatically. Polaris uses this to find your .env file. If this setting isn’t present, Polaris will try to use the POLARIS_ENV_PATH setting. It should be the path to the .env file.

BASE_DIR = "<path to your django project's top-level directory>"

Optionally, you can add Polaris’ logger to your LOGGING configuration. For example:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        }
    },
    'loggers': {
        'myapp': {
            'handlers': ['console'],
            'propogate': True,
            'LEVEL': 'DEBUG'
        },
        'polaris': {
            'handlers': ['console'],
            'propagate': True,
            'LEVEL': 'INFO'
        },
    }
}

You may want to configure the LEVEL of the Polaris logger differently depending on whether you’re running the service locally or in production. One way to do this by reading a POLARIS_LOG_LEVEL variable, or something similar, from the project’s environment.

Environment Variables

Polaris uses environment variables that should be defined in the environment or included in BASE_DIR/.env or POLARIS_ENV_PATH.

STELLAR_NETWORK_PASSPHRASE="Test SDF Network ; September 2015"
HORIZON_URI="https://horizon-testnet.stellar.org/"
HOST_URL="https://example.com"

Polaris also supports specifying your environment variables in your project’s settings.py. However, any variable Polaris expects in the environment must be prepended with POLARIS_ if declared in settings.py`. For example,

POLARIS_STELLAR_NETWORK_PASSPHRASE = "Test SDF Network ; September 2015"
POLARIS_HORIZON_URI = "https://horizon-testnet.stellar.org/"
POLARIS_HOST_URL = "https://example.com"

If a variable cannot be found in the environment, Polaris will look in the settings.py file, or more generally, django.conf.settings. Be careful not to check in secrets like your SERVER_JWT_KEY into your version control history, especially if your repository is not private.

Endpoints

Add the Polaris endpoints in urls.py

import polaris.urls
from django.urls import path, include

urlpatterns = [
    ...,
    path("", include(polaris.urls)),
]

Once you have implemented all the steps above, go to the documentation for each SEP you want the anchor server to support and follow the configuration instructions. Once your SEPs are configured, you can build the database and create your an Asset object.

Database Models

SEP-1, 6, and 24 require Polaris’ database models. Polaris currently only supports PostgreSQL and uses psycopg2 to connect to the database. If you use another database, file an issue in the project’s github repository.

Run migrations to create these tables in your database.

python manage.py migrate

Now, create an Asset database object for each asset you intend to anchor. Get into your python shell, then run something like this:

from polaris.models import Asset
Asset.objects.create(
    code="USD",
    issuer="<the issuer address>",
    distribution_seed="<distribution account secret key>",
    significant_decimals=2,
    deposit_fee_fixed=1,
    deposit_fee_percent=2,
    withdrawal_fee_fixed=1,
    withdrawal_fee_percent=2,
    deposit_min_amount=10,
    deposit_max_amount=10000,
    withdrawal_min_amount=10,
    withdrawal_max_amount=10000,
    sep24_enabled=True,
    sep6_enabled=True
)

The distribution_seed column is encrypted at the database layer using Fernet symmetric encryption, and only decrypted when held in memory within an Asset object. It uses your Django project’s SECRET_KEY setting to generate the encryption key, so make sure its value is unguessable and kept a secret.

See the Asset documentation for more information on the fields used.

At this point, you should configure Polaris for one or more of the SEPs currently supported. Once configured, check out how to run the server as described in the next section.

Running the Web Server

Production

Polaris should only be deployed using HTTPS in production. You should do this by using a HTTPS web server or running Polaris behind a HTTPS reverse proxy. The steps below outline the settings necessary to ensure your deployment is secure.

To redirect HTTP traffic to HTTPS, add the following to settings.py:

SECURE_SSL_REDIRECT = True

And if you’re running Polaris behind a HTTPS proxy:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

This tells Django what header to check and what value it should be in order to consider the incoming request secure.

Local Development

Locally, Polaris can be run using Django’s HTTP development server

python manage.py runserver

If you’re using Polaris’ SEP-24 support, you also need to use the following environment variable:

LOCAL_MODE=1

This is necessary to disable SEP-24’s interactive flow authentication mechanism, which requires HTTPS. Do not use local mode in production.

Contributing

To set up the development environment or run the SDF’s reference server, run follow the instructions below.

git clone git@github.com:stellar/django-polaris.git
cd django-polaris

Then, add a .env file in the example directory. You’ll need to create a signing account on Stellar’s testnet and add it to your environment variables.

DJANGO_SECRET_KEY="supersecretdjangokey"
DJANGO_DEBUG=True

SIGNING_SEED=<your signing account seed>

STELLAR_NETWORK_PASSPHRASE="Test SDF Network ; September 2015"

# For multi-sig MULT asset anchored by the reference server
# Should be empty if not anchoring MULT
MULT_ASSET_ADDITIONAL_SIGNING_SEED=""

HORIZON_URI="https://horizon-testnet.stellar.org/"
SERVER_JWT_KEY="your jwt local secret"
DJANGO_ALLOWED_HOSTS=localhost,0.0.0.0,127.0.0.1
HOST_URL="http://localhost:8000"
LOCAL_MODE=True

Next, you’ll need to create an asset on the Stellar test network and setup a distribution account. See this tool for creating assets on testnet.

Now you’re ready to add your asset to Polaris. Run the following commands:

$ docker-compose build
$ docker-compose up server

Go to http://localhost:8000/admin and login with the default credentials (root, password).

Go to the Assets menu, and click “Add Asset”

Enter the code, issuer, and distribution seed for the asset. Make sure that the asset is enabled for SEP-24 and SEP-6 by selecting the Deposit Enabled, Withdrawal Enabled, and either both or one of Sep24 Enabled and Sep6 Enabled.

Click Save.

Finally, kill the current docker-compose process and run a new one:

$ docker-compose up

You should now have a anchor server running SEP 6 & 24 on port 8000. When you make changes locally, the docker containers will restart with the updated code.

Testing

You can install the dependencies locally in a virtual environment:

pip install pipenv
cd django-polaris
pipenv install --dev
pipenv run pytest -c polaris/pytest.ini

Or, you can simply run the tests from inside the docker container. However, this may be slower.

docker exec -it server pytest -c polaris/pytest.ini

Submit a PR

After you’ve made your changes, push them to you a remote branch and make a Pull Request on the stellar/django-polaris master branch.