Skip to content
This repository has been archived by the owner on Jul 25, 2023. It is now read-only.

Merge upvestco faucet into toknapp faucet #1

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,5 @@ docs/*.json
# IDE stuff
.vscode/

upload.sh
sqlite3.db
env.list
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
FROM python:3.7.4-alpine3.9
FROM python:3.7.4-alpine3.10

RUN apk add --no-cache --virtual build-deps build-base
RUN apk add postgresql-dev \
libffi-dev \
openssl-dev
RUN apk add libffi-dev openssl-dev

RUN adduser --disabled-password --gecos '' --home /faucet faucet

Expand All @@ -22,6 +20,8 @@ RUN apk del build-deps

USER faucet

ENV UPVEST_USER_AGENT="upvest-faucet/docker"

COPY --chown=faucet:faucet faucet /faucet/app
WORKDIR /faucet/app
COPY --chown=faucet:faucet entrypoint.sh /faucet/entrypoint.sh
Expand Down
101 changes: 101 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Upvest Faucet

This is a demonstration project to show how to set up and run a very
simple application on the Upvest API.

With a few credentials, it will run as a simple faucet, dispensing tokens
or coins to whichever address requests it.

The purpose is to have an example of how to send from a wallet once it
has been created and funded on the Upvest API.

# Step 1 : Create a faucet user and wallet

First, [login to or create your Upvest account](http://login.upvest.co). After
that, you will have an application on the sandbox API to be able to use testnet
tokens and coins.

Using your API key, you will need to first create a user in your application.
This user will be the one used by the faucet to access wallets and create transactions.

Once you have a user, create one or more wallets for that user for the tokens or
coins you wish to serve from your faucet.

You can read up on how to create a user and wallet in [the quickstart guides](https://doc.upvest.co/docs/command-line-quickstart) in the documentation.

# Step 2 : Configure the faucet

Now that you have a user and a wallet, you need to configure the faucet to
use them. This is done via setting the following environment variables:

```
# the OAuth values for your application:
export UPVEST_OAUTH_CLIENT_ID=...
export UPVEST_OAUTH_CLIENT_SECRET=...
# the username and password of the user you created in your application:
export UPVEST_USERNAME=<username>
export UPVEST_PASSWORD=<password>
```

When running, the faucet application will use these credentials to authenticate
as the application user, fetching the list of wallets. Note that every single
wallet is assumed to be a faucet!

# Step 3 : How to run

First, if you haven't already, you will probably want to fund your faucet wallets
from one of the public faucets, for example for Ethereum Ropsten: https://faucet.ropsten.be

## From dockerhub

If you just want to run your own faucet, you don't even need to check out the
repository. Add those environment variables to a docker envfile, so for example `env.list`:

```
UPVEST_OAUTH_CLIENT_ID=...
UPVEST_OAUTH_CLIENT_SECRET=...
UPVEST_USERNAME=<username>
UPVEST_PASSWORD=<password>
```

Then run:

`docker run --env-file env.list -p 80:8000 upvest/faucet`

Then you can visit the faucet at http://127.0.0.1.

## From the repository via docker-compose

If you have checked out this repository, simply run:

`docker-compose up`

Then you can visit http://127.0.0.1.

## Running Django directly

If you have checked out the repository, you can create a Python3 virtualenv
and install and run this Django project. This is the best way to run if you
want to experiment and edit the code too.

First install the dependencies:

`pip install -e .[dev]`

Then `cd` into the faucet application directory and setup the database:

```
python manage.py migrate
python manage.py loaddata faucets
```

By default this will create a local sqlite database, you can change this by
setting the `DATABASE_URL` environment variable. There is nothing useful in the
database except the greylist though: all wallet balance and transaction data is
from the Upvest API.

Now you can run the server:

`python manage.py runserver`

Then you can visit http://127.0.0.1:8000
5 changes: 0 additions & 5 deletions default-env.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
export SECRET_KEY=seekretquai
export DEBUG=True
export DATABASE_URL=postgres://faucet:faucet@localhost:6041/faucet
export CELERY_BROKER_URL='amqp://guest:[email protected]:6042'
export ALLOWED_HOSTS='*'

export USE_SENTRY=False
export USE_STATSD=False
43 changes: 9 additions & 34 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,48 +1,23 @@
version: '3'
version: '2'

services:

# data stores
db:
image: postgres
environment:
- POSTGRES_USER=faucet
- POSTGRES_PASSWORD=faucet
- POSTGRES_DB=faucet
ports:
- 6041:5432
volumes:
- pgdata:/var/lib/postgresql/data

broker:
image: rabbitmq:latest
ports:
- 60542:5672
volumes:
- rabbitdata:/var/lib/rabbitmq

faucet:
image: faucet:latest
build:
context: .
dockerfile: Dockerfile
ports:
- 8000:8000
- 80:8000
environment:
- DATABASE_URL=postgres://faucet:faucet@db:5432/faucet
- SECRET_KEY=secret_sshhh
- STATIC_ROOT=/faucet/static/
- UPVEST_OAUTH_CLIENT_ID
- UPVEST_OAUTH_CLIENT_SECRET
- UPVEST_USERNAME
- UPVEST_PASSWORD
- UPVEST_WALLET_ID
- WHITELISTED_IPS=''
- WHITELISTED_HEADERS=''
depends_on:
- db
- broker

volumes:
pgdata:
rabbitdata:
- WHITELISTED_IPS
- WHITELISTED_HEADERS
- ALLOWED_HOSTS
- DEBUG
- USE_STATSD
- STATSD_HOST
- STATSD_PORT
9 changes: 4 additions & 5 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ See the README for how to configure this faucet: https://github.com/upvestco/dem
fi


if [ -z "$UPVEST_USERNAME" ] || [ -z "$UPVEST_PASSWORD" ] || [ -z "$UPVEST_WALLET_ID" ]; then
if [ -z "$UPVEST_USERNAME" ] || [ -z "$UPVEST_PASSWORD" ]; then
echo "
The credentials for the user and the wallet to use must be set as environment variables:
UPVEST_USERNAME
UPVEST_PASSWORD
UPVEST_WALLET_ID
See the README for how to configure this faucet: https://github.com/upvestco/demo-faucet/README.md
"
exit 1
Expand All @@ -27,12 +26,12 @@ fi
set -x

echo "Migrating database"
python manage.py migrate --no-input
python manage.py migrate --no-input > /dev/null

echo "Collecting static files"
python manage.py collectstatic --no-input
python manage.py collectstatic --no-input > /dev/null

echo "Loading asset definitions"
python manage.py loaddata assets
python manage.py loaddata faucets > /dev/null

gunicorn -c gunicorn.conf faucet.wsgi
33 changes: 0 additions & 33 deletions faucet/core/fixtures/assets.yaml

This file was deleted.

16 changes: 16 additions & 0 deletions faucet/core/fixtures/faucets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- model: core.faucet
pk: 1
fields:
asset_code: ETH
name: Ethereum (Ropsten)
asset_id: deaaa6bf-d944-57fa-8ec4-2dd45d1f5d3f
sending_amount: '0.01'
fee: '0.0001'
- model: core.faucet
pk: 2
fields:
asset_code: UP
name: Upvest Testing ERC20 Faucet (Ropsten)
asset_id: cf08564b-8fa3-5c88-a29b-029915471249
sending_amount: '1000000.0'
fee: '0.0001'
14 changes: 14 additions & 0 deletions faucet/core/migrations/0004_auto_20190904_1344.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Generated by Django 2.2.4 on 2019-09-04 13:44

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [("core", "0003_auto_20190816_0730")]

operations = [
migrations.RemoveField(model_name="faucet", name="visible"),
migrations.RemoveField(model_name="faucet", name="wallet_address"),
migrations.RemoveField(model_name="faucet", name="wallet_id"),
]
41 changes: 5 additions & 36 deletions faucet/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
from django.conf import settings
from django.db import models
from django.utils import timezone
from decimal import Decimal


from upvest.clientele import UpvestClienteleAPI


def greylisted(address, ip):
Expand Down Expand Up @@ -34,56 +30,29 @@ class Faucet(models.Model):
asset_id = models.UUIDField(unique=True)
""" The ID of the asset in the Upvest API """

wallet_id = models.UUIDField()
""" The ID of the wallet in the Upvest API """

wallet_address = models.CharField(max_length=64)
""" The public address of the wallet """

sending_amount = models.DecimalField(max_digits=40, decimal_places=15)
""" How much of the asset should sent on each sending request """

fee = models.DecimalField(max_digits=40, decimal_places=15)
""" How much to set as the sending fee """

visible = models.BooleanField()
""" Whether to include this asset or not, useful to turn off an asset """

def send(self, receive_address, ip):
def send(self, wallet, receive_address, ip):
# record the request first to prevent too many requests
DonationRequest.objects.create(address=receive_address, ip=ip)

wallet = self._get_wallet()
balance = self._get_balance()

balance = self.get_balance(wallet)
# the internal representation is the more human-friendly decimal version
# but the API accepts only whole integers
quantity = int(self.sending_amount * (10 ** balance["exponent"]))
fee = int(self.fee * (10 ** balance["exponent"]))
return wallet.transactions.create(settings.UPVEST_PASSWORD, str(self.asset_id), quantity, fee, receive_address)
return wallet.transactions.create(settings.UPVEST_PASSWORD, str(self.asset_id), quantity, fee, receive_address, asynchronous=True)

@property
def balance(self):
bal = self._get_balance()
balance = Decimal(bal["amount"]) / (10 ** bal["exponent"])
return balance.normalize()

def _get_balance(self):
wallet = self._get_wallet()
def get_balance(self, wallet):
for bal in wallet.balances:
if bal["asset_id"] == str(self.asset_id):
return bal
raise ValueError("No balance for asset %s" % self.asset_id)

def _get_wallet(self):
api = UpvestClienteleAPI(
settings.UPVEST_OAUTH_CLIENT_ID,
settings.UPVEST_OAUTH_CLIENT_SECRET,
settings.UPVEST_USERNAME,
settings.UPVEST_PASSWORD,
base_url=settings.UPVEST_BACKEND,
)
return api.wallets.get(str(self.wallet_id))

def __str__(self):
visible = "visible" if self.visible else "not visible"
return "Sending %s %s (%s)" % (self.sending_amount, self.asset_code, visible)
Expand Down
7 changes: 0 additions & 7 deletions faucet/core/static/css/bootstrap.min.css

This file was deleted.

Binary file modified faucet/core/static/favicon.ico
Binary file not shown.
Loading