Extension set up

Start off by creating a fork of the example extension into own GitHub repository and rename the repository to mysuperplugin:

cd [my-working-folder]
git clone https://github.com/[my-user-name]/mysuperplugin.git --depth=1 # Let's not use dashes or anything; it doesn't like those.
cd mysuperplugin
rm -rf .git/
find . -type f -print0 | xargs -0 sed -i 's/example/mysuperplugin/g' # Change all occurrences of 'example' to your plugin name 'mysuperplugin'.
mv templates/example templates/mysuperplugin # Rename templates folder.
  • if you are on macOS and having difficulty with ‘sed’, consider brew install gnu-sed and use ‘gsed’, without -0 option after xargs.
  1. Edit manifest.json and change the organisation name to your GitHub username.
  2. Push your changes to GitHub.
  3. In GitHub create a new release for your extension repo. Tag the release with 0.0.1
  4. Copy the URL of the extension’s raw manifest.json URL https://raw.githubusercontent.com/[my-user-name]/mysuperplugin/master/manifest.json
  5. If you are using the LMNbits Admin UI, go to the Admin UI > Server > Extension Sources, click “Add”, paste the URL, then click “Save”
  6. If you are configuring LNbits via environment variables, add the URL to the .env file’s LNBITS_EXTENSIONS_MANIFESTS variable. Restart the LNbits python process
  7. You will now see your extension in the LNbits > Extensions list. Click “Enable” to enable it.
  8. Profit!!!

Extension structure explained

  • views_api.py: This is where your public API would go. It will be exposed at “$DOMAIN/$PLUGIN/$ROUTE”. For example: https://lnbits.com/mysuperplugin/api/v1/tools.
  • views.py: The / path will show up as your plugin’s home page in lnbits’ UI. Other pages you can define yourself. The templates folder should explain itself in relation to this.
  • migrations.py: Create database tables for your plugin. They’ll be created automatically when you start lnbits.

… This document is a work-in-progress. Send pull requests if you get stuck, so others don’t.

Adding new dependencies

DO NOT ADD NEW DEPENDENCIES. Try to use the dependencies that are available in pyproject.toml. Getting the LNbits project to accept a new dependency is time consuming and uncertain, and may result in your extension NOT being made available to others.

If for some reason your extensions must have a new python package to work, and its nees are not met in pyproject.toml, you can add a new package using poerty:

$ poetry add <package>

But we need an extra step to make sure LNbits doesn’t break in production. Dependencies need to be added to pyproject.toml, then tested by running on poetry compatibility can be tested with nix build .#checks.x86_64-linux.vmTest.

SQLite to PostgreSQL migration

LNbits currently supports SQLite and PostgreSQL databases. There is a migration script tools/conv.py that helps users migrate from SQLite to PostgreSQL. This script also copies all extension databases to the new backend.

Adding mock data to mock_data.zip

mock_data.zip contains a few lines of sample SQLite data and is used in automated GitHub test to see whether your migration in conv.py works. Run your extension and save a few lines of data into a SQLite your_extension.sqlite3 file. Unzip tests/data/mock_data.zip, add your_extension.sqlite3, updated database.sqlite3 and zip it again. Add the updated mock_data.zip to your PR.

running migration locally

you will need a running postgres database

create lnbits user for migration database

sudo su - postgres -c "psql -c 'CREATE ROLE lnbits LOGIN PASSWORD 'lnbits';'"

create migration database

sudo su - postgres -c "psql -c 'CREATE DATABASE migration;'"

run the migration

make test-migration

sudo su - postgres -c “psql -c ‘CREATE ROLE lnbits LOGIN PASSWORD ‘lnbits’;’”

clean migration database afterwards, fails if you try again

sudo su - postgres -c "psql -c 'DROP DATABASE IF EXISTS migration;'"