Initial catalog migrated from aiolabs/lnbits:main extensions.json

This commit is contained in:
Padreug 2026-05-07 11:33:42 +02:00
commit 8719e9f01b
2 changed files with 327 additions and 0 deletions

71
README.md Normal file
View file

@ -0,0 +1,71 @@
# lnbits-extensions — aiolabs catalog manifest
A standalone catalog of LNbits extensions we make available across our
deployments. Just `extensions.json` + this README — no server code.
## Why this is its own repo
`extensions.json` is a **catalog** (what's available), not a
**dependency** (what's installed). Keeping it out of the lnbits server
fork (`aiolabs/lnbits`) means:
- The server fork's `main` can be locked-down and slow-moving — only
real server code goes through PR review.
- Catalog updates (new versions, new extensions, deprecating an entry)
happen here on a different cadence and review bar.
- Hosts pull the catalog at runtime via `LNBITS_EXTENSIONS_MANIFESTS`,
so promoting a new extension version is a single commit here, not a
rebuild of every lnbits host.
## How hosts consume it
Server-deploy sets `services.lnbits.env.LNBITS_EXTENSIONS_MANIFESTS` to
the raw URL of `extensions.json` on this repo's `main`:
```
https://git.atitlan.io/aiolabs/lnbits-extensions/raw/branch/main/extensions.json
```
LNbits fetches that URL on boot, builds the in-app catalog from it, and
verifies each downloaded archive against the per-entry `hash` field
(sha256). That `hash` is the integrity guarantee — without a matching
sha256, lnbits refuses to install. So even though the manifest itself
is fetched at runtime, the *artifacts* installed are content-addressed.
## How to add or update an entry
Each entry has a stable schema (see `extensions.json`); the required
fields are `id`, `repo`, `name`, `version`, `short_description`,
`archive`, and `hash`.
To add a new extension or version:
1. Tag a release in the source extension repo (e.g.
`git.atitlan.io/aiolabs/<extension>` `v0.0.5`).
2. Compute the sha256 of the archive:
```sh
curl -sL https://git.atitlan.io/aiolabs/<ext>/archive/v0.0.5.zip \
| sha256sum
```
3. Append a new object to `extensions.extensions[]`. Multiple versions
of the same `id` are allowed — lnbits picks the highest the host's
`min_lnbits_version` permits.
4. Commit + push to `main`. Hosts pick up the change on next lnbits
restart.
## Featured extensions
`extensions.featured[]` is the array of `id`s shown prominently in the
lnbits "Manage Extensions" UI. Add an `id` here when an extension is
considered the canonical choice for a category (e.g. `libra` for
accounting); remove when superseded.
## Why we don't include the lnbits upstream manifest
We could chain ours with
`https://raw.githubusercontent.com/lnbits/lnbits-extensions/main/extensions.json`
in `LNBITS_EXTENSIONS_MANIFESTS`, but a tight curated catalog is a
feature, not a limitation, for our deployments — every available
extension on a host is one we've explicitly vetted. The upstream
catalog is mirrored at `~/dev/refs/repos/lnbits/lnbits-extensions/` for
awareness if we want to lift a specific extension.

256
extensions.json Normal file
View file

@ -0,0 +1,256 @@
{
"featured": [
"satmachineclient",
"libra"
],
"extensions": [
{
"id": "satmachineadmin",
"repo": "https://git.atitlan.io/aiolabs/satmachineadmin",
"name": "Satoshi Machine Admin",
"min_lnbits_version": "1.4.0",
"version": "0.0.3",
"short_description": "Admin Dashboard for Satoshi Machine",
"icon": "https://git.atitlan.io/aiolabs/satmachineadmin/raw/branch/main/static/image/aio.png",
"archive": "https://git.atitlan.io/aiolabs/satmachineadmin/archive/v0.0.3.zip",
"hash": "0cf520ee62037298320d8c0caa6f15d89858447d826af53472cb369023eda46d"
},
{
"id": "satmachineadmin",
"repo": "https://git.atitlan.io/aiolabs/satmachineadmin",
"name": "Satoshi Machine Admin",
"version": "0.0.4",
"short_description": "Admin Dashboard for Satoshi Machine",
"icon": "https://git.atitlan.io/aiolabs/satmachineadmin/raw/branch/main/static/image/aio.png",
"archive": "https://git.atitlan.io/aiolabs/satmachineadmin/archive/v0.0.4.zip",
"hash": "f5a6e33e6379984964cd0a4b25225770c4356c5c8a62c8e811b712775a180615"
},
{
"id": "satmachineadmin",
"repo": "https://git.atitlan.io/aiolabs/satmachineadmin",
"name": "Satoshi Machine Admin",
"version": "0.0.5",
"short_description": "Admin Dashboard for Satoshi Machine",
"icon": "https://git.atitlan.io/aiolabs/satmachineadmin/raw/branch/main/static/image/aio.png",
"archive": "https://git.atitlan.io/aiolabs/satmachineadmin/archive/v0.0.5.zip",
"hash": "a342a349504c25eb99b5d9a45ea88ea6bfcc21d628068dde1b5fda374d01da68"
},
{
"id": "satmachineclient",
"repo": "https://git.atitlan.io/aiolabs/satmachineclient",
"name": "Satoshi Machine Client",
"version": "0.0.1",
"short_description": "Client Dashboard for Satoshi Machine",
"icon": "https://git.atitlan.io/aiolabs/satmachineclient/raw/branch/main/static/image/aio.png",
"archive": "https://git.atitlan.io/aiolabs/satmachineclient/archive/v0.0.1.zip",
"hash": "05cf74b0f8a39953ad9c063c40a983d6223ebbfa906f5598b6ebe2c58eccfd9a"
},
{
"id": "events",
"repo": "https://git.atitlan.io/aiolabs/events",
"name": "AIO Events",
"version": "0.0.1",
"short_description": "AIO fork of aiolabs/events",
"icon": "https://git.atitlan.io/aiolabs/events/raw/branch/main/static/image/events.png",
"archive": "https://git.atitlan.io/aiolabs/events/archive/v0.0.1.zip",
"hash": "410ac9c340551aabe88e0dc7393ed30dc7f4703f1345af5e6b02b0ebc5337d52"
},
{
"id": "events",
"repo": "https://git.atitlan.io/aiolabs/events",
"name": "AIO Events",
"version": "0.0.2",
"short_description": "AIO fork of aiolabs/events",
"icon": "https://git.atitlan.io/aiolabs/events/raw/branch/main/static/image/events.png",
"archive": "https://git.atitlan.io/aiolabs/events/archive/v0.0.2.zip",
"hash": "4ac140b97b164f81c482cc19da07a79e961685ae146dc89cba6d12e7d5e80716"
},
{
"id": "events",
"repo": "https://git.atitlan.io/aiolabs/events",
"name": "AIO Events",
"version": "1.2.1-aio.1",
"short_description": "AIO fork of lnbits/events",
"icon": "https://git.atitlan.io/aiolabs/events/raw/branch/main/static/image/events.png",
"archive": "https://git.atitlan.io/aiolabs/events/archive/v1.2.1-aio.1.zip",
"hash": "73fa1f8859d6e776768b0669002701707a423781474a57780bed68f70a2b7841"
},
{
"id": "events",
"repo": "https://git.atitlan.io/aiolabs/events",
"name": "AIO Events",
"version": "1.2.1-aio.2",
"short_description": "NIP-52 Nostr publishing, approval workflow, bidirectional sync",
"icon": "https://git.atitlan.io/aiolabs/events/raw/branch/main/static/image/events.png",
"archive": "https://git.atitlan.io/aiolabs/events/archive/v1.2.1-aio.2.zip",
"hash": "d20b7c9ee23b5d9ef71528408da94a127a2ef40277b2b30ee7e78e644da55df8"
},
{
"id": "events",
"repo": "https://git.atitlan.io/aiolabs/events",
"name": "AIO Events",
"version": "1.3.0-aio.1",
"short_description": "Rebased onto upstream v1.3.0; approval workflow, NIP-52 bidirectional Nostr sync, optional user_id tickets",
"icon": "https://git.atitlan.io/aiolabs/events/raw/branch/main/static/image/events.png",
"archive": "https://git.atitlan.io/aiolabs/events/archive/v1.3.0-aio.1.zip",
"hash": "d7a5f3110eae5402af2d64a890ea6aa8e112c47dd5ce6299224e0231f0706cb0"
},
{
"id": "events",
"repo": "https://git.atitlan.io/aiolabs/events",
"name": "AIO Events",
"version": "1.3.0-aio.2",
"short_description": "Rebased onto upstream v1.3.0; approval workflow, NIP-52 bidirectional Nostr sync, optional user_id tickets",
"icon": "https://git.atitlan.io/aiolabs/events/raw/branch/main/static/image/events.png",
"archive": "https://git.atitlan.io/aiolabs/events/archive/v1.3.0-aio.2.zip",
"hash": "ccfa652dc0a5ca2474fa138f9ed6af15a33db7f211e3b66cb162bbfe04be2be0"
},
{
"id": "nostrclient",
"repo": "https://git.atitlan.io/aiolabs/nostrclient",
"name": "AIO nostrclient",
"version": "0.0.1",
"short_description": "AIO fork of aiolabs/nostrclient",
"icon": "https://git.atitlan.io/aiolabs/nostrclient/raw/branch/main/static/images/nostr-bitcoin.png",
"archive": "https://git.atitlan.io/aiolabs/nostrclient/archive/v0.0.1.zip",
"hash": "7f0b1861243a10d16d41d17bc6e64616d61c6b299a86f40dc1a0f9cfc7f9725a"
},
{
"id": "nostrclient",
"repo": "https://git.atitlan.io/aiolabs/nostrclient",
"name": "AIO nostrclient",
"version": "1.2.0-aio.1",
"short_description": "AIO fork of lnbits/nostrclient",
"icon": "https://git.atitlan.io/aiolabs/nostrclient/raw/branch/main/static/images/nostr-bitcoin.png",
"archive": "https://git.atitlan.io/aiolabs/nostrclient/archive/v1.2.0-aio.1.zip",
"hash": "7f0b1861243a10d16d41d17bc6e64616d61c6b299a86f40dc1a0f9cfc7f9725a"
},
{
"id": "nostrmarket",
"repo": "https://git.atitlan.io/aiolabs/nostrmarket",
"name": "AIO nostrmarket",
"version": "0.0.1",
"short_description": "AIO fork of aiolabs/nostrmarket",
"icon": "https://git.atitlan.io/aiolabs/nostrmarket/raw/branch/main/static/image/bitcoin-shop.png",
"archive": "https://git.atitlan.io/aiolabs/nostrmarket/archive/v0.0.1.zip",
"hash": "7599485232c600c00896caac15c0fdec07aef26d2cce95c9b2df85b9807bf4f3"
},
{
"id": "nostrmarket",
"repo": "https://git.atitlan.io/aiolabs/nostrmarket",
"name": "AIO nostrmarket",
"version": "1.1.0-aio.1",
"short_description": "AIO fork of lnbits/nostrmarket",
"icon": "https://git.atitlan.io/aiolabs/nostrmarket/raw/branch/main/static/image/bitcoin-shop.png",
"archive": "https://git.atitlan.io/aiolabs/nostrmarket/archive/v1.1.0-aio.1.zip",
"hash": "edfd11c995a091f71f6439038e6d6ca06cd591abea114e6ac306a6ed5854eb6a"
},
{
"id": "nostrmarket",
"repo": "https://git.atitlan.io/aiolabs/nostrmarket",
"name": "AIO nostrmarket",
"version": "1.1.0-aio.2",
"short_description": "AIO fork of lnbits/nostrmarket",
"icon": "https://git.atitlan.io/aiolabs/nostrmarket/raw/branch/main/static/image/bitcoin-shop.png",
"archive": "https://git.atitlan.io/aiolabs/nostrmarket/archive/v1.1.0-aio.2.zip",
"hash": "35bd9d20ef43a108ad3b6f0f6a64e3ba56a5b9938ebcf4839f8bc72f3058b23d"
},
{
"id": "nostrmarket",
"repo": "https://git.atitlan.io/aiolabs/nostrmarket",
"name": "AIO nostrmarket",
"version": "1.1.0-aio.3",
"short_description": "AIO fork of lnbits/nostrmarket",
"icon": "https://git.atitlan.io/aiolabs/nostrmarket/raw/branch/main/static/image/bitcoin-shop.png",
"archive": "https://git.atitlan.io/aiolabs/nostrmarket/archive/v1.1.0-aio.3.zip",
"hash": "f887d25768586920b21c564afd526e218f42bb2ce114b5934c182be1dacb9897"
},
{
"id": "nostrrelay",
"repo": "https://git.atitlan.io/aiolabs/nostrrelay",
"name": "AIO Nostrrelay",
"version": "0.0.2",
"short_description": "AIO fork of aiolabs/nostrrelay",
"icon": "https://git.atitlan.io/aiolabs/nostrrelay/raw/branch/main/static/image/nostrrelay.png",
"archive": "https://git.atitlan.io/aiolabs/nostrrelay/archive/v0.0.2.zip",
"hash": "6e353358314b740679e55e2ff98c7024a97c6df8bf27d1784e8cee448407bebd"
},
{
"id": "nostrrelay",
"repo": "https://git.atitlan.io/aiolabs/nostrrelay",
"name": "AIO Nostrrelay",
"version": "1.1.0-aio.1",
"short_description": "AIO fork of lnbits/nostrrelay",
"icon": "https://git.atitlan.io/aiolabs/nostrrelay/raw/branch/main/static/image/nostrrelay.png",
"archive": "https://git.atitlan.io/aiolabs/nostrrelay/archive/v1.1.0-aio.1.zip",
"hash": "0826d16b985be4e9199841223ccd6777aa85120fb6f576dc00c159fef37dd61f"
},
{
"id": "nostrrelay",
"repo": "https://git.atitlan.io/aiolabs/nostrrelay",
"name": "AIO Nostrrelay",
"version": "1.1.0-aio.2",
"short_description": "AIO fork of lnbits/nostrrelay",
"icon": "https://git.atitlan.io/aiolabs/nostrrelay/raw/branch/main/static/image/nostrrelay.png",
"archive": "https://git.atitlan.io/aiolabs/nostrrelay/archive/v1.1.0-aio.2.zip",
"hash": "2f5435b4849b7d1e8f4af456d88ad336f78132d5db0ec5d60efe304034c1c5cc"
},
{
"id": "withdraw",
"repo": "https://git.atitlan.io/aiolabs/withdraw",
"name": "AIO Withdraw",
"version": "1.2.2-aio.1",
"short_description": "AIO fork of lnbits/withdraw",
"icon": "https://github.com/lnbits/withdraw/raw/main/static/image/lnurl-withdraw.png",
"archive": "https://git.atitlan.io/aiolabs/withdraw/archive/v1.2.2-aio.1.zip",
"hash": "38c9baf92966b6d8bdb13af12cf324cff4bafd19510cd56650d69e864011492d"
},
{
"id": "libra",
"repo": "https://git.atitlan.io/aiolabs/libra",
"name": "Libra",
"version": "0.1.0",
"short_description": "Double-entry accounting for collectives",
"icon": "https://git.atitlan.io/aiolabs/libra/raw/branch/main/static/image/libra.png",
"archive": "https://git.atitlan.io/aiolabs/libra/archive/v0.1.0.zip",
"hash": "b3dc77d95047b3ef0733bd2ae761b547bc8d2275cb022ec071a1ab276d9683da"
},
{
"id": "lnurlp",
"repo": "https://github.com/lnbits/lnurlp",
"name": "Pay Links",
"version": "1.1.3",
"min_lnbits_version": "1.3.0",
"short_description": "Make reusable LNURL pay links",
"icon": "https://github.com/lnbits/lnurlp/raw/main/static/image/lnurl-pay.png",
"details_link": "https://raw.githubusercontent.com/lnbits/lnurlp/main/config.json",
"archive": "https://github.com/lnbits/lnurlp/archive/refs/tags/v1.1.3.zip",
"hash": "913b6880fd824e801f05ae50ed6f57817c9a580f1ed1b02b435823d5754e1b98",
"max_lnbits_version": "1.4.0"
},
{
"id": "lnurlp",
"repo": "https://github.com/lnbits/lnurlp",
"name": "Pay Links",
"version": "1.3.0",
"min_lnbits_version": "1.4.0",
"short_description": "Make reusable LNURL pay links",
"icon": "https://github.com/lnbits/lnurlp/raw/main/static/image/lnurl-pay.png",
"details_link": "https://raw.githubusercontent.com/lnbits/lnurlp/main/config.json",
"archive": "https://github.com/lnbits/lnurlp/archive/refs/tags/v1.3.0.zip",
"hash": "71701b5756628fec6d7418192158c647e840e1fbf9a65e6fd2372bc73f626562"
},
{
"id": "lnurlp",
"repo": "https://github.com/lnbits/lnurlp",
"name": "Pay Links",
"version": "1.2.0",
"min_lnbits_version": "1.4.0",
"short_description": "Make reusable LNURL pay links",
"icon": "https://github.com/lnbits/lnurlp/raw/main/static/image/lnurl-pay.png",
"details_link": "https://raw.githubusercontent.com/lnbits/lnurlp/main/config.json",
"archive": "https://github.com/lnbits/lnurlp/archive/refs/tags/v1.2.0.zip",
"hash": "d3872eb5f65b9e962fc201d6784f94f3fd576284582b980805142a2b3f62d8e8"
}
]
}