The monero faucet can be used as stagenet faucet or as testnet faucet.
A faucet in general accepts a monero wallet address and returns a fraction of its own wallet's balance to the given wallet.
Running faucets based on this project can be found at
Visit us at https://community.xmr.to.
These instructions will get you a copy of the faucet up and running on your local machine for development and testing purposes.
See deployment for notes on how to deploy the project on a live system.
Before you even start to use docker-compose to run a faucet locally, you should make a copy of docker-compose-template.yml.
cp docker-compose-template.yml docker-compose.ymlIn docker-compose.yml you will find some settings, you should be familiar with (default settings refer to docker-compose.yml, not settings.py):
- faucet specific
FACTOR_BALANCE(default:10)- The factor by which the wallet's balance is divided. Determines the amount to pay to the given address.
WALLET_HOST(default:localhost)- IP or URL to the
monero -wallet-rpc(seemonero-rpcservice)
- IP or URL to the
WALLET_PORT(default:38083)- RPC port of the
monero -wallet-rpc(seemonero-rpcservice)
- RPC port of the
DAEMON_HOST(default:node.xmr.to)- IP or URL to
monerod
- IP or URL to
DAEMON_PORT(default:38081)- RPC port of
monerod
- RPC port of
DEFAULT_MIXIN(default:10)- mixin to be used when making transactions (
ring size = mixin + 1)
- mixin to be used when making transactions (
FAUCET_PORT(default:8000)- Published port of the faucet
- If changed, also modify
- exposed port in
docker-compose.yml commandindocker-compose.ymltorunserver 0.0.0.0:<your_port>
- exposed port in
- service/project specific
RATELIMIT_ENABLE(default:True)- switches on/off rate limitation on the
transactions/endpoint. - not working locally, since
django-ratelimitis configured to readheader:x-real-ipinstead ofip.- if set to
ip,django-ratelimittries to readremote_addr. - A Middleware could be added to modify
remote_addrand always useipin thedjango-ratelimitconfiguration.
- if set to
- Makes use of
django-ratelimit.
- switches on/off rate limitation on the
ONCE_EVERY_N_MINUTE(default:5)- configures the faucet's rate limitation on API endpoint
transactions/to once pernminutes wheren=ONCE_EVERY_N_MINUTE.
- configures the faucet's rate limitation on API endpoint
MAXIMUM_PAYOUT(default:1)- sets the maximum XMR to pay to the user to
1 XMR - This was implemented due to the fact, that someone was draining the faucet with a script.
- sets the maximum XMR to pay to the user to
DEBUG(default:True)- Should be set to
Falsein production
- Should be set to
SECRET_KEY(default:<some_secret_key>)- This value should be changed to something sensible in production.
MONERO_ENDPOINT(default:/)- Is only changed when several faucets are served by one single proxy server (like nginx).
- See deployment for further information.
CACHE_URL(default:locmemcache://)- URL to cache
locmemcache://uses the local Django cache- See 'Starting the faucet' for use with redis.
- Makes use of
django-environ.
- URL to cache
DATABASE_URL(default:sqlite://)- URL to database
sqlite://creates an in-memory sqlite databasesqlite:////data/db.developcreates a sqlite database file calleddb.devlop- See 'Starting the faucet' for use with postgres.
- Makes use of
django-environ.
- URL to database
A monero-wallet-rpc docker image is hosted here. The source can be found here.
The service monero-rpc does not publish its port (not listening on host's localhost). The port is just exposed, which makes it available in the faucet service, since they are hosted within the same docker/docker-compose network.
Modify monero-rpc service in docker-compose.yml.
USER_ID(default:1000)- Can be set to whatever
uidthe wallet folder is owned by.- Within the docker container a user (with the given
uid=USER_ID) is created.
- Within the docker container a user (with the given
- Obviousy only works, if
uidis available.
- Can be set to whatever
LOG_LEVEL- verbosity level of
monero-wallet-rpclog messages
- verbosity level of
- stagenet
--stagenet--wallet-file <stagenet_wallet>--password-file <stagenet_wallet_password_file>- Adapt the path to your monero stagenet wallet
<stagenet_wallet>. DAEMON_PORT=38081(or whatever port your daemon is listening to)wallet_port=38083(or whatever port yout RPC should be listening on)
- testnet
--testnet--wallet-file <testnet_wallet>--password-file <testnet_wallet_password_file>- Adapt the path to your monero testnet wallet
<testnet_wallet>. DAEMON_PORT=28081(or whatever port your daemon is listening to)wallet_port=28083(or whatever port yout RPC should be listening on)
The faucet project makes use of docker and docker-compose.
The following tools should be installed to make it work locally:
dockerdocker-compose
The faucet can be started like this
docker-compose up -d --buildThe above command starts the faucet service as well as a monero-wallet-rpc server (as defined within docker-compose.yml).
It also makes sure, the service's image is built from scratch (--build) and the services (docker containers) are started in the background (-d, daemonized).
The local development environment's (Dockerfile) docker base image (faucet service) is based on python:3.6 (docker-compose-template.yml).
For production (prod.Dockerfile) docker base image(faucet service) should be based on python:3.6-alpine (docker-compose-prod.yml). Please see deployment for more information.
Have a look at the logs:
docker-compose log -fdocker-compose log -f faucet(onlyfaucetservice)
Stop services:
docker-compose rm -s -fdocker-compose rm -s -f faucet(onlyfaucetservice)
The default database (docker-compose-template.yml) is sqlite.
Using the setting DATABASE_URL the database can be easily changed.
-
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/transactions -
DATABASE_URL=sqlite:////data/db.develop -
sqlite- uncomment
sqliteindepends_on(indocker-compose.yml) - uncomment
sqliteDATABASE_URL - comment
postgresDATABASE_URL - comment
postgresindepends_on(indocker-compose.yml) - comment the
postgresservice (indocker-compose.yml) - comment the
volumes(indocker-compose.yml)
- uncomment
-
postgres- comment
sqliteindepends_on(indocker-compose.yml) - comment
sqliteDATABASE_URL - uncomment
postgresDATABASE_URL - uncomment
postgresindepends_on(indocker-compose.yml) - uncomment the
postgresservice (indocker-compose.yml) - uncomment the
volumes(indocker-compose.yml)
- comment
In the same manner the cache can be configured.
CACHE_URL=rediscache://redis:6379/1?CLIENT_CLASS=django_redis.client.DefaultClient
With its default configuration the faucet listens on port 8000.
Tests can be run using the script
start_local_tests.sh
This script spins up a docker container and runs the tests within this specific environment.
Have a look at docker-compose-testing.yml for further details.
Of course, it is also possible to run the faucet service and enter the container using docker-compose exec faucet bash.
Then you should be able to activate and enter the virtual environment with pipenv shell.
From here on, it is possible to run Django commands like python manage.py ....
The source code is formatted using black --line-length 79.
For the deployment we recommend using alpine as docker base image.
prod.Dockerfile makes use of this - Locally such an environment can be started with docker-compose-prod.yml as docker-compose configuration file.
docker-compose -f docker-compose-prod.yml up -d --buildIn this case DEBUG should be set to False'
Another command line within docker-compose.yml can be used to let the faucet be served by uWSGI.
In this case, comment the command containing runserver 0.0.0.0....
The uWSGI server listens on port FAUCET_PORT.
STATIC_ROOT = "/data/static/" and uWSGI is configured to serve statc content like this --static-map /static/=/data/static/.
There might be the need to run stagenet and testnet faucets behind the same nginx proxy.
In this case it is recommended to let the faucet be served by uWSGI.
This requires to differentiate
- API calls
- static content requests between the two faucets.
Therefore MONERO_ENDPOINT was introduced. This setting defines a URL prefix, that is used when the client talks to the backend.
MONERO_ENDPOINT modifies the following settings:
- URL to static content in
index.html - URL to
transactions/API endpoint inindex.htmlby modifiyingSTATIC_URLinsettings.py.
MONERO_ENDPOINT should be the same as the appropriate location block in the nginx configuration.
Within the nginx location block the prefixed URL should be stripped of MONERO_ENDPOINT again, since uWSGI is configured to just serve static contents
- With
MONERO_ENDPOINT=/STATIC_URLbecomes/static/index.html/transactions//static/fonts/fonts.css
- With
MONERO_ENDPOINT=/faucet/stagenet/STATIC_URLbecomes/faucet/stagenet/static/index.html/faucet/stagenet/transactions//faucet/stagenet/static/fonts/fonts.css...
- With
MONERO_ENDPOINT=/faucet/testnet/STATIC_URLbecomes/faucet/testnet/static/index.html/faucet/testnet/transactions//faucet/testnet/static/fonts/fonts.css...
nginx could be configured like this:
set $upstream_faucet_testnet some_ip_url_dns_to_the_testnet_faucet:8000;
location ~ ^/faucet/testnet/ {
if ($request_method !~ ^(GET|POST|HEAD|OPTIONS)$) {
return 405;
}
# forwarding
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $http_x_real_ip;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
# use the complete $request_uri for rewriting
rewrite ^ $request_uri;
# remove /faucet/testnet/
# take the remaining content and put it into $uri
rewrite ^/faucet/testnet/(.*) /$1 break; # add / before $1 to avoid zero length $uri
return 400; #if the second rewrite does not match
proxy_pass http://$upstream_faucet_testnet$uri;
}
Eventually, this setup requests the backend with /transactions/ instead of /faucet/testnet/transactions/, which is the configured URL.
Also static content will be requested from /static/fonts/fonts.css instead of /faucet/testnet/fonts/fonts.css, like the uWSGI configuration defines.
The services are run within docker containers.
The faucet service is backed by python3.6.
The virtual environment for python is created and maintained with pipenv.
Specific versions are defined within Pipfile.
django-environis used to to extract database URLs as well as cache URLs.django-ratelimitis used to rate throttle API endpoints.djangorestframeworkis used to create a REST API.
We use SemVer for versioning. For the versions available, see the tags on this repository.
- Norman Moeschter-Schenck - Initial work - normoes
See also the list of contributors who participated in this project.
This project is licensed under the Apache 2.0 License - see the LICENSE file for details
makemigrations could, in some cases, be interactive (e.g. renaming a model field).
Then, the faucet container will not start successfully.
- Leave the
faucetservice in its unsuccessful state
# enter the running faucet service container
docker-compose exec faucet bash
# enter the virtual environment
pipenv shell
# run makemigrations manually
python manage.py makemigrations # interactive