Lightning balance CLI
npm install balanceofsatoshisCommands for working with LND balances.


Supported LND versions:
- v0.20.0-beta
- v0.19.0-beta to v0.19.3-beta
- v0.18.0-beta to v0.18.5-beta
- v0.17.0-beta to v0.17.5-beta
- v0.16.0-beta to v0.16.4-beta
- v0.15.2-beta to v0.15.5-beta
- Requires an [installation of Node v20+][nodejs-install-guide]
``shell`
npm install -g balanceofsatoshis
Or use a platform-specific guide:
- Docker/BTCPayServer install notes
- [RaspiBlitz install guide][raspiblitz-install-guide]
- [RaspiBolt/Debian guide][raspibolt-install-guide]
- [Umbrel install guide][umbrel-install-guide]
If you want to try out any command without npm install, you can also do npx
balanceofsatoshis to run a command directly.
Get the version to verify that it's installed:
`shell`
bos --versioncurrent installed version
Re-install if you want to update to a new version.
To see a list of available options and flags run:
`shell
bos help
Community
Use
bos trade-secret and buy the secret
626f73ff0001010425002302210288be11d147e1525f7f234f304b094d6627d2c70f3313d7ba3696887b261c4447
to gain access to the private Telegram group.Or if you can't use bos yet you can ask about it on the
public group
$3
`shell
See an accounting formatted list of various types of transactions
bos accounting "category"See total balance, including pending funds, excluding future commit fees
bos balanceGet the number of days the node cert remains valid
bos cert-validity-daysReceive on-chain funds via a regular address
bos chain-depositSee the current fee estimates confirmation targets
bos chainfeesShow chain fees paid
bos chart-chain-feesShow routing fees earned
bos chart-fees-earnedShow routing fees paid
bos chart-fees-paidShow a chart of payments received
bos chart-payments-receivedRemove old failed payment data for probes and other failed payments
bos clean-failed-paymentsSee details on how closed channels resolved on-chain
bos closedExport credentials
bos credentialsView outbound fee rates and update outbound fee rates to peers
bos feesQuery the node to find something like a payment, channel or node
bos find "query"Output a summarized version of peers forwarded towards
bos forwardsCreate a signed raw transaction for an on-chain transfer
bos fund "address" "amount"See help about a command
bos help "command"Run gateway service for https://ln-operator.github.io/ UI
bos gatewayLook up the channels and fee rates of a node by its public key
bos graph "pubkey"Output the sum total of remote channel liquidity
bos inbound-liquidityEnforce rules on inbound channels
bos inbound-channel-rulesIncrease inbound liquidity to the node
bos increase-inbound-liquidityIncrease the outbound liquidity of the node
bos increase-outbound-liquidityView and adjust list of saved nodes
bos nodesOpen channels to public keys in a batch transaction
bos open "public_keys..."Open a balanced channel with a peer
bos open-balanced-channelOutputs the sum total of local channel liquidity
bos outbound-liquidityPay a payment request (invoice), probing first
bos pay "payment_request"Show channel-connected peers
bos peersOutput the price of BTC
bos priceTest if funds can be sent to a destination
bos probe "payment_request/public_key"Rebalance funds between peers
bos rebalanceRemove all channels with a peer
bos remove-peerGet a general report of the node activity
bos reportSend funds using keysend and an optional message to a node
bos sendConnect up to a Telegram bot
bos telegramUnlock the wallet if it is locked
bos unlock "path_to_password_file"Show unspent coin outputs
bos utxos
`Community HowTos:
- The
accounting command howto
- The open command howto
- The rebalance command howto
- Another rebalance command howto
- Running rebalance video (In German)
- Secrets of rebalance command revealed
- Running telegram via nohup/tmux howto
- Running telegram via systemd
- Another rebalance + tags & telegram commands howto
- Documentation for bos commands commands howtoWant to stack some sats? Write your own LN paywalled guide!
Nodes
By default
bos expects tls.cert in the root of the default lnd directory
and admin.macaroon in .Default LND directories:
* macOS:
~/Library/Application Support/Lnd/
* Linux: ~/.lnd/It will check first for a mainnet macaroon, then a testnet macaroon.
The LND directory can be overriden with an environment variable:
BOS_DEFAULT_LND_PATH=/path/to/lnd/data/dir$3
If you have another node and it is already using
balanceofsatoshis, you can
add it as a "saved node" using bos nodes --add.Otherwise you can copy the credentials into a saved nodes directory:
To use
bos with arbitrary external nodes (or nodes with custom
configuration), two things need to be done:1. Create directory
~/.bos/, and add node credentials in a format of:
~/.bos/YOUR_NODE_NAME/credentials.jsonUse any shorthand you'd like when choosing this profile node name
2. Each file should have the following format:
`json
{
"cert": "base64 tls.cert value",
"macaroon": "base64 .macaroon value",
"socket": "host:port"
}
`Note:
cert and (admin) macaroon should have base64-encoded, and newline-stripped content of the files. To get the strings in appropriate format you can run, ex:`bash
For
cert
base64 -w0 ~/.lnd/tls.certFor
macaroon
base64 -w0 ~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon
`Note_2:
socket should contain host:port pointing to lnd's gRPC interface, localhost:10009 by convention.
You can also set cert_path and macaroon_path to the path of the relevant
files instead.The BOS directory path can be overriden with an environment variable:
BOS_DATA_PATH=/path/to/bos/data/dir#### Umbrel Saved Node
Note: Umbrel is not FOSS software, use at your own risk.
If you are using Umbrel and you have already installed but you get an error like
Name resolution failed for target dns:umbrel.local:10009 then try adding
umbrel.local to your /etc/hosts file, like sudo nano /etc/hosts and add a line 127.0.0.1 umbrel.local1. Identify your Umbrel home dir, like /home/umbrel/umbrel
2. Look in the .env file in that dir for the
LND_IP to use as the socket to
connect toYou can also use umbrel.local if that is in your Umbrel TLS cert but you will
have to make sure the hostname is known to the client.
`
{
"cert_path": "/home/umbrel/umbrel/app-data/lightning/data/lnd/tls.cert",
"macaroon_path": "/home/umbrel/umbrel/app-data/lightning/data/lnd/data/chain/bitcoin/mainnet/admin.macaroon",
"socket": "LND_IP:10009"
}
`5. Now when you do a command, specify
--node umbrel or whatever your dir is: bos --node umbrel balance$3
To run commands on nodes specified this way, you need to suffix commands with
their name, ex:
`shell
bos balance --node=SAVED_NODE_NAME
bos forwards --node=SAVED_NODE_NAME
`If a saved node is actually your default node, you can set an environment
variable to avoid adding the --node prefix
export BOS_DEFAULT_SAVED_NODE=nodenameIf that is set, it will use that node if no node is specified.
You can also add a JSON file to your .bos directory: config.json, add
{"default_saved_node": "nodename"} to set the default via a file insteadLinux Fu
Some commands are designed to return outputs that can be piped or used in other CLI programs.
$3
Make a textfile in the terminal with newline separated pubkeys and the capacity of the channels.
`shell
cat bos_channels.txt │ File: bos_channels.txt
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ 0337...1986 --amount=3000000
2 │ 02a4...20de --amount=3000000
3 │ 023c...0dec --amount=1000000
``shell
bos open $(cat bos_channels.txt)
`$3
`shell
expr $(bos balance --node=savedNode1) + $(bos balance --node=savedNode2)
outputs the combined balance of both nodes
`$3
`
Cron every 5 minutes adjust fees
/5 * /bin/timeout -s 2 30 /home/ubuntu/update-fees.sh
`update-fees.sh:
`
#!/bin/bash
Raise the outbound fees to a public key when inbound increases
/home/ubuntu/.npm-global/bin/bos fees --to PUBLIC_KEY --set-fee-rate="IF(INBOUND>10000000,1000,500)"
`$3
Keep a channel balanced between two of your own nodes
`
Cron: every 30 minutes send funds to reach 50:50
/30 /home/ubuntu/.npm-global/bin/bos send PUBKEY --max-fee 0 --message="rebalance" --amount="IF(OUTBOUND+1m>(LIQUIDITY/2), OUTBOUND-(LIQUIDITY/2), 0)"
`If you want to 50:50 rebalance with a peer node, you can use
--out-target-inbound=capacity/2 with bos rebalanceAlerts and Reports with
sendnotificationSome commands are made with the idea that they can trigger an alert or regular
report by piping the output of a command into some reporting script like
sendnotification which works
with AWS SNS service to deliver notifications
Examples of shell scripts that could be executed by crontab:
$3
`shell
cert-expiration-alert.sh
#!/bin/bash
/path/to/bos cert-validity-days --below 30 | \
/path/to/sendnotification SNS "sns-topic-id" "Warning: %s days left on TLS cert" \
--nonzero --subject="Cert expiration warning"
sends email when the certification has less than 30 days left until invalid
`$3
`shell
daily-report.sh
#!/bin/bash
/path/to/bos report --styled 2>&1 | \
/path/to/sendnotification SNS "sns-topic-id" "%s" --subject="Daily node update"
sends email about what has happened on the node in the past day
`$3
`shell
low-offchain-outbound-liquidity alert
#!/bin/bash
/path/to/bos balance --offchain --below 4000000 | \
/path/to/sendnotification SNS "sns-topic-id" "off-chain balance deficit: %s sats" \
--nonzero --subject="Low balance warning"
sends email if the channel balance goes below a threshold
`$3
`shell
low-inbound-liquidity.sh
#!/bin/bash
/path/to/bos inbound-liquidity --below=1000000 2>&1 | \
/path/to/sendnotification SNS "sns-topic-id" \
"WARNING inbound-liquidity deficit: %s sats" --nonzero \
--subject="Low inbound liquidity warning: node1"
sends email if the inbound liquidity drops below a 1,000,000 sats
`$3
If you are running a long-running command and want it to persist, you will need
something like Docker or nohup or tmux to assist you in that and then kill the
process and restart it when updating.
Nohup example:
`shell
nohup /home/bos/.npm-global/bin/bos telegram --connect CONNECT_CODE > /dev/null &
`Docker example:
`
docker run -d --restart always -v $HOME/.bos:/home/node/.bos alexbosworth/balanceofsatoshis telegram --connect CONNECT_CODE
`You can also create a shell-script.sh to run a command repeatedly, with a delay
`bash
while true;
do bos rebalance;
sleep 2000;
done
`Docker
This presumes you have Docker installed.
- [Instructions for installing Docker on Ubuntu][docker-install-guide]
Install the Docker image:
`shell
docker pull alexbosworth/balanceofsatoshis
`$3
You can also build the image yourself:
npm run build-docker, this will make
balanceofsatoshis.tar.gz that you can rsync or scp somewhere else and then
do docker load < balanceofsatoshis.tar.gz.Once the image is installed, you can "docker run" commands for all the commands:
`shell
Make sure you have a home directory created to give Docker access to
mkdir $HOME/.bosdocker run -it --rm -v $HOME/.bos:/home/node/.bos alexbosworth/balanceofsatoshis --version
Should output the version
`This maps your home directory to the docker home directory to enable
persistence of credentials.
If you want it to automatically detect your local node, also pass the LND home
dir as an additional -v argument to docker run:
If you are on MacOS:
`shell
--network="host" -v $HOME/Library/Application\ Support/Lnd/:/home/node/.lnd:ro
`Or on Linux:
`shell
--network="host" -v $HOME/.lnd:/home/node/.lnd:ro
`On BTCPayServer:
Create the credential.json file as explained in the saved nodes section, and for socket put:
"socket": "lnd_bitcoin:10009"For Docker network use the Docker bridged network:
`
docker run -it --rm --network="generated_default" -v $HOME/.bos:/home/node/.bos alexbosworth/balanceofsatoshis balance --node SAVEDNODENAME
`On Umbrel this would be:
`
add Umbrel specific details:
--network="host"
--add-host=umbrel.local:192.168.1.23
-v $HOME/umbrel/app-data/lightning/data/lnd:/home/node/.lnd:ro
docker run -it --rm --network=umbrel_main_network --add-host=localhost:10.21.21.9 -v $HOME/.bos:/home/node/.bos -v $HOME/umbrel/app-data/lightning/data/lnd:/home/node/.lnd:ro alexbosworth/balanceofsatoshis report
`Note: For umbrel-os users, when
running the above docker run command, ensure the "192.168.1.23" portion of the
command is updated to reflect the IP of the lnd container. You can find the IP
by looking for the
LND_IP value inside the $HOME/umbrel/.env file.Otherwise you can just pass the local node credentials as shown above using the
saved nodes.
If you are running a long-running command like
telegram, use -d --restart instead of -it --rm to run in daemon mode and auto-restart.Note: if you are used to using ctrl+c to terminate the process, that doesn't
work on Docker. Instead, you can use ctrl+p and then ctrl+q to background the
interactive mode, then do
docker ps and docker rm to kill the instance.$3
If you don't want to use the Dockerfile, you can build a docker file for
yourself
`dockerfile
FROM node:latest
RUN npm install balanceofsatoshis
ENTRYPOINT [ "/node_modules/balanceofsatoshis/bos" ]
`$3
If you don't want to type out "docker run", and don't have an alias for it, you
can create a simple shell script to fill that part in:
`shell
#! /usr/bin/env bash
docker run -it --rm -v=$HOME/.bos:/root/.bos bos:latest ${@:1}
`You can also define an alias for placing in
~/.profile or ~/.bash_profile:`shell
alias bos="docker run -it --rm -v $HOME/.bos:/home/node/.bos alexbosworth/balanceofsatoshis"
`Adjust this alias to however you run the full Docker command. Remember to
execute the ~/.profile to install the alias into your current session:
. You can also create an alias to run a command in the background
`shell
alias bosd="docker run -d --rm -v $HOME/.bos:/home/node/.bos alexbosworth/balanceofsatoshis"
`Formulas
Some commands take formula arguments. Formulas are expressions that allow you
to perform functions and reference variables.
There is a dynamic playground here where you can play with expressions:
https://formulajs.info/functions/
$3
In
--avoid flag commands like rebalance, a formula can be applied
directionally:--avoid "fee_rate < 100/ to avoid channels forwarding to the public
key that charge a fee rate under 100 PPM.Available variables:
-
age: Age of the channel vs the current height
- base_fee: Base fee to be charged to route
- capacity: Capacity of the channel
- fee_rate: PPM fee to be charged to route
- height: Absolute height of the channel
- opposite_fee_rate: PPM fee that is charged in the non-routing direction$3
Formula amounts are supported in the following commands:
-
fund
- inbound-channel-rules
- open
- probe
- rebalance
- sendWhen passing an amount you can pass a formula expression, and the following variables are
defined:
-
k: 1,000
- m: 1,000,000Examples:
`shell
bos fund "7*m"
// Fund address with value 7,000,000bos probe "100*k"
// Probe to key amount 100,000
bos send "m/2"
// Push 500,000 to key
`####
rebalanceRebalance defines additional variables for
--amount:-
capacity: The total of inbound and outboundAnd for
--in-filter and --out-filter:-
capacity: The total capacity with the peer
- heights: The set of heights of the channels with the peer
- inbound_fee_rate: The fee rate the peer is charging
- inbound_liquidity: The inbound liquidity with the peer
- outbound_liquidity: The outbound liquidity with the peer
- pending_payments: The number of pending paymentsExample:
`shell
// Rebalance with a target of 1,000,000
bos rebalance --amount "1*m"
`####
sendSend defines additional variables:
-
eur: The value of 1 Euro as defined by rate provider
- inbound: The inbound liquidity with the destination
- liquidity: The total capacity with the destination
- outbound: The inbound liquidity with the destination
- usd: The value of 1 US Dollar as defined by rate providerExample:
`shell
// Send node $1
bos send --amount "1*usd"
`####
transferTransfer variables:
-
out_inbound: The outbound liquidity with the outbound peer
- out_liquidity: The total inbound+outbound with the outbound peer
- out_outbound: The total outbound liquidity with the outbound peerExample:
`shell
// Equalize inbound with a mutual peer
bos transfer node "in_inbound - (in_inbound + out_inbound)/2" --through peer
`$3
Variables can be referenced for
--set-fee-rate-
fee_rate_of_: Reference other node's fee rate
- inbound: Remote balance with peer
- inbound_fee_rate: Incoming fee rate
- outbound: Local balance with peerYou can also use functions:
-
bips(n): Set fee as parts per thousand
- percent(0.00): Set fee as fractional percentageExample:
`shell
// Set the fee rate to a tag to 1% of the value forwarded
bos fees --to tag --set-fee-rate "percent(1)"
`$3
Pass formulas for rules with
--rule.Formula variables:
-
capacities: sizes of the peer's public channels
- capacity: size of the inbound channel
- channel_ages: block ages of the peer's public channels
- fee_rates: outbound fee rates for the peer
- local_balance: gifted amount on the incoming channel
- private: request is to open an unannounced channel
- public_key: key of the incoming peerExample:
`shell
// Reject channels that are smaller than 2,000,000 capacity
bos inbound-channel-rules --rule "capacity < 2*m"// Set separate capacity limits depending on private status
bos inbound-channel rules --rule "if(private,capacity >= 9m,capacity >= 5m)"
``[docker-install-guide]: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04
[nodejs-install-guide]: https://gist.github.com/alexbosworth/8fad3d51f9e1ff67995713edf2d20126
[raspiblitz-install-guide]: https://gist.github.com/openoms/823f99d1ab6e1d53285e489f7ba38602
[raspibolt-install-guide]: https://raspibolt.org/guide/bonus/lightning/balance-of-satoshis.html
[umbrel-install-guide]: https://web.archive.org/web/20240711203839/https://plebnet.wiki/wiki/Umbrel_-_Installing_BoS