Skip to content
Merged
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ npx skills add getAlby/hub-skill
- [Debug Tools](./references/debug-tools.md)
- [Channels](./references/channels.md)
- [Payments](./references/payments.md)
- [Swaps](./references/swaps.md)
- [Apps](./references/apps.md)
- [LSP](./references/lsp.md)
- [JIT Channels](./references/jit-channels.md)
Expand Down
5 changes: 3 additions & 2 deletions SKILL.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
name: alby-hub-skill
description: Manage a self-custodial Alby Hub lightning node via @getalby/hub-cli — setup, authentication, channels, LSP, backups, lightning and on-chain payments, and creating budgeted, scoped NWC app connections that give agents and apps controlled, revocable access to the wallet.
description: Manage a self-custodial Alby Hub lightning node via @getalby/hub-cli — setup, authentication, channels, LSP, backups, lightning and on-chain payments, swaps, and creating budgeted, scoped NWC app connections that give agents and apps controlled, revocable access to the wallet.
license: Apache-2.0
metadata:
author: getAlby
version: "0.1.4"
version: "0.1.5"
---

# Alby Hub Agent Skill
Expand Down Expand Up @@ -32,6 +32,7 @@ Use this skill to manage an Alby Hub lightning node via the CLI.
- [JIT Channels: Default first-receive flow on LDK — a channel opens just-in-time on the first payment, fee deducted from it (LDK only)](./references/jit-channels.md)
- [Channels: Open/close channels, peers, connect-peer, node connection info](./references/channels.md)
- [Payments: Pay/make invoices, transactions, lookup, balances, wallet address](./references/payments.md)
- [Swaps: Swap on-chain bitcoin ↔ lightning (swap in / swap out), powered by boltz.exchange — confirm amounts and addresses before swapping](./references/swaps.md)
- [Apps: NWC app management — create-app, list apps](./references/apps.md)
- [QR Codes: Display invoices and NWC connection strings as QR codes using qrencode](./references/qrcodes.md)
- [Custom Node Commands: Backend-specific node commands](./references/custom-node-commands.md)
Expand Down
7 changes: 7 additions & 0 deletions references/payments.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ npx -y @getalby/hub-cli@0.5.0 get-balances
# Get an on-chain deposit address
npx -y @getalby/hub-cli@0.5.0 get-onchain-address

# Send an on-chain payment from the hub's on-chain wallet (confirm with human if channels are open and amount may cause anchor reserves may be drained)
npx -y @getalby/hub-cli@0.5.0 pay-onchain bc1... --amount 100000

# Sweep the entire on-chain balance to an address (confirm with human if any channels are open - anchor reserves will be drained)
npx -y @getalby/hub-cli@0.5.0 pay-onchain bc1... --all

# Pay a BOLT11 invoice
npx -y @getalby/hub-cli@0.5.0 pay-invoice lnbc...

Expand Down Expand Up @@ -45,3 +51,4 @@ On **LDK**, if the hub has no channel yet, a `make-invoice` for an amount above
- `--amount` for `pay-invoice` is in millisatoshis (msat). Use for zero-amount invoices only.
- `--amount` for `make-invoice` is in millisatoshis.
- `get-balances` returns both lightning (channel) and on-chain balances. This is the **hub wallet** balance — it is **not** the balance of any individual app.
- `pay-onchain` `--amount` is in **sats**, and spends from the **on-chain** wallet (not lightning). Use `--all` to sweep the whole on-chain balance instead of `--amount`. The address is **not validated for you** — read the full address back to the user and get explicit confirmation before sending; an on-chain payment is irreversible.
80 changes: 80 additions & 0 deletions references/swaps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Swaps

Swap between **on-chain bitcoin** and **lightning**, powered by [boltz.exchange](https://boltz.exchange):

- **Swap in** — on-chain bitcoin → lightning balance.
- **Swap out** — lightning balance → on-chain bitcoin (the hub's own on-chain wallet, or an external address).

Swaps are **bitcoin ↔ bitcoin**. The only "other cryptocurrency" path is via FixedFloat (see the end of this page).

## ⚠️ Fund safety — confirm before every swap

A swap moves real funds and **cannot be undone**. Before running any swap command, **always confirm with the user in plain language**:

1. **The direction** (in or out) and **the amount** in **satoshis** (sats).
2. **For swap out:** the destination — the hub's own on-chain wallet, or an **external on-chain address**. If external, **read the full address back to the user and get explicit confirmation** — a wrong address means irreversible loss of funds, and the address is not validated for you. Payment will be initiated immediately and cannot be reversed.
3. **For swap in:** how it will be funded — from the **hub's on-chain wallet** or an **external wallet** (see the flow below).
4. **That fees apply** (see below).

Only run the command once the user has confirmed. Never guess the amount or an address.

## Swap in (on-chain → lightning)

This is a **two-step** flow:

1. **Generate the swap** with `swap-in --amount <sats>`. This returns the swap details, including:
- `lockupAddress` — the on-chain bitcoin address to deposit to.
- `sendAmountSat` — the **exact** on-chain amount to deposit (this is higher than the requested amount; it includes the boltz fees).
- `id` — the swap ID, and `state` (starts as `PENDING`).

**Show the user the deposit address and the exact amount.** You can display it as a QR code (`bitcoin:<lockupAddress>?amount=<amountInBTC>`, where `amountInBTC = sendAmountSat / 100000000`) — see [QR Codes](./qrcodes.md).

2. **Fund the deposit.** Send exactly `sendAmountSat` to `lockupAddress` from any on-chain wallet — the user's external wallet, or the hub's own on-chain balance. The user sends the shown amount to the shown address themselves; there is no swap-specific CLI step for this. You can offer to pay with the hub's on-chain funds, but the human should confirm before any action is taken.

Once the deposit confirms on-chain, boltz pays the hub's lightning invoice and the swap reaches `SUCCESS`. Track progress with `lookup-swap <id>`.

```bash
# 1. Generate a swap to receive 100,000 sats on lightning
npx -y @getalby/hub-cli@0.5.0 swap-in --amount 100000

# 2. Send the shown sendAmountSat to the shown lockupAddress from any on-chain wallet
```

## Swap out (lightning → on-chain)

`swap-out` spends from the hub's lightning balance and pays the boltz invoice automatically, then claims the on-chain funds to the destination — there is no second step.

```bash
# Swap lightning out into the hub's own on-chain wallet (amount received on-chain, in sats)
npx -y @getalby/hub-cli@0.5.0 swap-out --amount 100000

# Swap lightning out to an external on-chain address
npx -y @getalby/hub-cli@0.5.0 swap-out --amount 100000 --destination bc1...
```

- `--amount` is the amount **received on-chain**, in **sats**. boltz adds its fees on top, so the lightning amount actually spent (`sendAmountSat`) is higher.
- Omitting `--destination` swaps into the hub's own on-chain wallet; providing it sends to an external on-chain address.

## Checking a swap

```bash
# Look up a swap by its swap ID (state is PENDING, SUCCESS, FAILED or REFUNDED)
npx -y @getalby/hub-cli@0.5.0 lookup-swap <swapId>
```

## Before swapping

- Check balances first with `get-balances`. Swap **out** needs enough **lightning** spendable balance (amount + fees); swap **in** funded from the hub needs enough **on-chain** spendable balance (`sendAmountSat` + on-chain fees).
- Fees are `albyServiceFee% + boltzServiceFee% + on-chain fees`. boltz also enforces minimum and maximum swap amounts; an out-of-range amount is rejected with an error message.

## Swap to/from another cryptocurrency

To swap into or out of a **different cryptocurrency** (e.g. an external ETH/USDT address), there is no boltz swap — it goes through [FixedFloat](https://ff.io):

- **Out to another coin:** send the user `https://ff.io/?from=BTCLN&ref=qnnjvywb`. They choose the target coin and address; FixedFloat returns a **lightning invoice**; pay it from the hub with `pay-invoice` (see [Payments](./payments.md)) after confirming the amount.
- **In from another coin:** create a lightning invoice with `make-invoice`, then send the user `https://ff.io/?to=BTCLN&address=<invoice>&ref=qnnjvywb` to pay it with their other cryptocurrency.

## Notes

- All swap amounts are in **sats**, not millisats (unlike `pay-invoice` / `make-invoice`).
- If a swap shows `FAILED`, advise the user that locked-up funds can be recovered via the **Swap Refund** tool in the Alby Hub web interface (Settings → Debug Tools). CLI refunds are not yet supported.
3 changes: 0 additions & 3 deletions references/unsupported-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ The hub CLI is experimental and incomplete. The following features are **not** a

## Bitcoin & liquidity

- Swaps (manual swaps in/out)
- Auto-swaps
- Buy bitcoin
- Exchange bitcoin with stablecoin / crypto
- Pay for a channel with stablecoin / crypto
- Send on-chain payments

## Node & wallet management

Expand Down